Hi Alexander,

Thank you again, this is really promising and I think I get the gist of it.
I have just one issue left: The /24 prefix keeps showing as unreachable.

I have set up a test peer (both sides) to verify that routes come through.

Here is my config:

protocol bgp test
{
        local as 64512;
        source address 10.55.55.251;
        import none;
        export filter {
                # announce all of our sub-prefixes
                if(net ~ [192.0.2.0/24{25,32}]) then accept;

                # if at least one of them is reachable, announce the entire /24
                if(net = 192.0.2.0/24 && dest != RTD_UNREACHABLE) then accept;

                reject;
        };
        neighbor 10.55.55.250 as 65534;
        password "xyz";
        multihop 2;
}

protocol static prefix_aggregation
{
route 192.0.2.0/24 recursive 192.0.2.0;
route 192.0.2.0/24 recursive 192.0.2.1;
route 192.0.2.0/24 recursive 192.0.2.2;
route 192.0.2.0/24 recursive 192.0.2.3;
route 192.0.2.0/24 recursive 192.0.2.4;
route 192.0.2.0/24 recursive 192.0.2.5;
route 192.0.2.0/24 recursive 192.0.2.6;
route 192.0.2.0/24 recursive 192.0.2.7;
route 192.0.2.0/24 recursive 192.0.2.8;
route 192.0.2.0/24 recursive 192.0.2.9;
route 192.0.2.0/24 recursive 192.0.2.10;
route 192.0.2.0/24 recursive 192.0.2.11;
route 192.0.2.0/24 recursive 192.0.2.12;
route 192.0.2.0/24 recursive 192.0.2.13;
route 192.0.2.0/24 recursive 192.0.2.14;
route 192.0.2.0/24 recursive 192.0.2.15;
route 192.0.2.0/24 recursive 192.0.2.16;
route 192.0.2.0/24 recursive 192.0.2.17;
route 192.0.2.0/24 recursive 192.0.2.18;
route 192.0.2.0/24 recursive 192.0.2.19;
route 192.0.2.0/24 recursive 192.0.2.20;
route 192.0.2.0/24 recursive 192.0.2.21;
route 192.0.2.0/24 recursive 192.0.2.22;
route 192.0.2.0/24 recursive 192.0.2.23;
route 192.0.2.0/24 recursive 192.0.2.24;
route 192.0.2.0/24 recursive 192.0.2.25;
route 192.0.2.0/24 recursive 192.0.2.26;
route 192.0.2.0/24 recursive 192.0.2.27;
route 192.0.2.0/24 recursive 192.0.2.28;
route 192.0.2.0/24 recursive 192.0.2.29;
route 192.0.2.0/24 recursive 192.0.2.30;
route 192.0.2.0/24 recursive 192.0.2.31;
route 192.0.2.0/24 recursive 192.0.2.32;
route 192.0.2.0/24 recursive 192.0.2.33;
route 192.0.2.0/24 recursive 192.0.2.34;
route 192.0.2.0/24 recursive 192.0.2.35;
route 192.0.2.0/24 recursive 192.0.2.36;
route 192.0.2.0/24 recursive 192.0.2.37;
route 192.0.2.0/24 recursive 192.0.2.38;
route 192.0.2.0/24 recursive 192.0.2.39;
route 192.0.2.0/24 recursive 192.0.2.40;
route 192.0.2.0/24 recursive 192.0.2.41;
route 192.0.2.0/24 recursive 192.0.2.42;
route 192.0.2.0/24 recursive 192.0.2.43;
route 192.0.2.0/24 recursive 192.0.2.44;
route 192.0.2.0/24 recursive 192.0.2.45;
route 192.0.2.0/24 recursive 192.0.2.46;
route 192.0.2.0/24 recursive 192.0.2.47;
route 192.0.2.0/24 recursive 192.0.2.48;
route 192.0.2.0/24 recursive 192.0.2.49;
route 192.0.2.0/24 recursive 192.0.2.50;
route 192.0.2.0/24 recursive 192.0.2.51;
route 192.0.2.0/24 recursive 192.0.2.52;
route 192.0.2.0/24 recursive 192.0.2.53;
route 192.0.2.0/24 recursive 192.0.2.54;
route 192.0.2.0/24 recursive 192.0.2.55;
route 192.0.2.0/24 recursive 192.0.2.56;
route 192.0.2.0/24 recursive 192.0.2.57;
route 192.0.2.0/24 recursive 192.0.2.58;
route 192.0.2.0/24 recursive 192.0.2.59;
route 192.0.2.0/24 recursive 192.0.2.60;
route 192.0.2.0/24 recursive 192.0.2.61;
route 192.0.2.0/24 recursive 192.0.2.62;
route 192.0.2.0/24 recursive 192.0.2.63;
route 192.0.2.0/24 recursive 192.0.2.64;
route 192.0.2.0/24 recursive 192.0.2.65;
route 192.0.2.0/24 recursive 192.0.2.66;
route 192.0.2.0/24 recursive 192.0.2.67;
route 192.0.2.0/24 recursive 192.0.2.68;
route 192.0.2.0/24 recursive 192.0.2.69;
route 192.0.2.0/24 recursive 192.0.2.70;
route 192.0.2.0/24 recursive 192.0.2.71;
route 192.0.2.0/24 recursive 192.0.2.72;
route 192.0.2.0/24 recursive 192.0.2.73;
route 192.0.2.0/24 recursive 192.0.2.74;
route 192.0.2.0/24 recursive 192.0.2.75;
route 192.0.2.0/24 recursive 192.0.2.76;
route 192.0.2.0/24 recursive 192.0.2.77;
route 192.0.2.0/24 recursive 192.0.2.78;
route 192.0.2.0/24 recursive 192.0.2.79;
route 192.0.2.0/24 recursive 192.0.2.80;
route 192.0.2.0/24 recursive 192.0.2.81;
route 192.0.2.0/24 recursive 192.0.2.82;
route 192.0.2.0/24 recursive 192.0.2.83;
route 192.0.2.0/24 recursive 192.0.2.84;
route 192.0.2.0/24 recursive 192.0.2.85;
route 192.0.2.0/24 recursive 192.0.2.86;
route 192.0.2.0/24 recursive 192.0.2.87;
route 192.0.2.0/24 recursive 192.0.2.88;
route 192.0.2.0/24 recursive 192.0.2.89;
route 192.0.2.0/24 recursive 192.0.2.90;
route 192.0.2.0/24 recursive 192.0.2.91;
route 192.0.2.0/24 recursive 192.0.2.92;
route 192.0.2.0/24 recursive 192.0.2.93;
route 192.0.2.0/24 recursive 192.0.2.94;
route 192.0.2.0/24 recursive 192.0.2.95;
route 192.0.2.0/24 recursive 192.0.2.96;
route 192.0.2.0/24 recursive 192.0.2.97;
route 192.0.2.0/24 recursive 192.0.2.98;
route 192.0.2.0/24 recursive 192.0.2.99;
route 192.0.2.0/24 recursive 192.0.2.100;
route 192.0.2.0/24 recursive 192.0.2.101;
route 192.0.2.0/24 recursive 192.0.2.102;
route 192.0.2.0/24 recursive 192.0.2.103;
route 192.0.2.0/24 recursive 192.0.2.104;
route 192.0.2.0/24 recursive 192.0.2.105;
route 192.0.2.0/24 recursive 192.0.2.106;
route 192.0.2.0/24 recursive 192.0.2.107;
route 192.0.2.0/24 recursive 192.0.2.108;
route 192.0.2.0/24 recursive 192.0.2.109;
route 192.0.2.0/24 recursive 192.0.2.110;
route 192.0.2.0/24 recursive 192.0.2.111;
route 192.0.2.0/24 recursive 192.0.2.112;
route 192.0.2.0/24 recursive 192.0.2.113;
route 192.0.2.0/24 recursive 192.0.2.114;
route 192.0.2.0/24 recursive 192.0.2.115;
route 192.0.2.0/24 recursive 192.0.2.116;
route 192.0.2.0/24 recursive 192.0.2.117;
route 192.0.2.0/24 recursive 192.0.2.118;
route 192.0.2.0/24 recursive 192.0.2.119;
route 192.0.2.0/24 recursive 192.0.2.120;
route 192.0.2.0/24 recursive 192.0.2.121;
route 192.0.2.0/24 recursive 192.0.2.122;
route 192.0.2.0/24 recursive 192.0.2.123;
route 192.0.2.0/24 recursive 192.0.2.124;
route 192.0.2.0/24 recursive 192.0.2.125;
route 192.0.2.0/24 recursive 192.0.2.126;
route 192.0.2.0/24 recursive 192.0.2.127;
route 192.0.2.0/24 recursive 192.0.2.128;
route 192.0.2.0/24 recursive 192.0.2.129;
route 192.0.2.0/24 recursive 192.0.2.130;
route 192.0.2.0/24 recursive 192.0.2.131;
route 192.0.2.0/24 recursive 192.0.2.132;
route 192.0.2.0/24 recursive 192.0.2.133;
route 192.0.2.0/24 recursive 192.0.2.134;
route 192.0.2.0/24 recursive 192.0.2.135;
route 192.0.2.0/24 recursive 192.0.2.136;
route 192.0.2.0/24 recursive 192.0.2.137;
route 192.0.2.0/24 recursive 192.0.2.138;
route 192.0.2.0/24 recursive 192.0.2.139;
route 192.0.2.0/24 recursive 192.0.2.140;
route 192.0.2.0/24 recursive 192.0.2.141;
route 192.0.2.0/24 recursive 192.0.2.142;
route 192.0.2.0/24 recursive 192.0.2.143;
route 192.0.2.0/24 recursive 192.0.2.144;
route 192.0.2.0/24 recursive 192.0.2.145;
route 192.0.2.0/24 recursive 192.0.2.146;
route 192.0.2.0/24 recursive 192.0.2.147;
route 192.0.2.0/24 recursive 192.0.2.148;
route 192.0.2.0/24 recursive 192.0.2.149;
route 192.0.2.0/24 recursive 192.0.2.150;
route 192.0.2.0/24 recursive 192.0.2.151;
route 192.0.2.0/24 recursive 192.0.2.152;
route 192.0.2.0/24 recursive 192.0.2.153;
route 192.0.2.0/24 recursive 192.0.2.154;
route 192.0.2.0/24 recursive 192.0.2.155;
route 192.0.2.0/24 recursive 192.0.2.156;
route 192.0.2.0/24 recursive 192.0.2.157;
route 192.0.2.0/24 recursive 192.0.2.158;
route 192.0.2.0/24 recursive 192.0.2.159;
route 192.0.2.0/24 recursive 192.0.2.160;
route 192.0.2.0/24 recursive 192.0.2.161;
route 192.0.2.0/24 recursive 192.0.2.162;
route 192.0.2.0/24 recursive 192.0.2.163;
route 192.0.2.0/24 recursive 192.0.2.164;
route 192.0.2.0/24 recursive 192.0.2.165;
route 192.0.2.0/24 recursive 192.0.2.166;
route 192.0.2.0/24 recursive 192.0.2.167;
route 192.0.2.0/24 recursive 192.0.2.168;
route 192.0.2.0/24 recursive 192.0.2.169;
route 192.0.2.0/24 recursive 192.0.2.170;
route 192.0.2.0/24 recursive 192.0.2.171;
route 192.0.2.0/24 recursive 192.0.2.172;
route 192.0.2.0/24 recursive 192.0.2.173;
route 192.0.2.0/24 recursive 192.0.2.174;
route 192.0.2.0/24 recursive 192.0.2.175;
route 192.0.2.0/24 recursive 192.0.2.176;
route 192.0.2.0/24 recursive 192.0.2.177;
route 192.0.2.0/24 recursive 192.0.2.178;
route 192.0.2.0/24 recursive 192.0.2.179;
route 192.0.2.0/24 recursive 192.0.2.180;
route 192.0.2.0/24 recursive 192.0.2.181;
route 192.0.2.0/24 recursive 192.0.2.182;
route 192.0.2.0/24 recursive 192.0.2.183;
route 192.0.2.0/24 recursive 192.0.2.184;
route 192.0.2.0/24 recursive 192.0.2.185;
route 192.0.2.0/24 recursive 192.0.2.186;
route 192.0.2.0/24 recursive 192.0.2.187;
route 192.0.2.0/24 recursive 192.0.2.188;
route 192.0.2.0/24 recursive 192.0.2.189;
route 192.0.2.0/24 recursive 192.0.2.190;
route 192.0.2.0/24 recursive 192.0.2.191;
route 192.0.2.0/24 recursive 192.0.2.192;
route 192.0.2.0/24 recursive 192.0.2.193;
route 192.0.2.0/24 recursive 192.0.2.194;
route 192.0.2.0/24 recursive 192.0.2.195;
route 192.0.2.0/24 recursive 192.0.2.196;
route 192.0.2.0/24 recursive 192.0.2.197;
route 192.0.2.0/24 recursive 192.0.2.198;
route 192.0.2.0/24 recursive 192.0.2.199;
route 192.0.2.0/24 recursive 192.0.2.200;
route 192.0.2.0/24 recursive 192.0.2.201;
route 192.0.2.0/24 recursive 192.0.2.202;
route 192.0.2.0/24 recursive 192.0.2.203;
route 192.0.2.0/24 recursive 192.0.2.204;
route 192.0.2.0/24 recursive 192.0.2.205;
route 192.0.2.0/24 recursive 192.0.2.206;
route 192.0.2.0/24 recursive 192.0.2.207;
route 192.0.2.0/24 recursive 192.0.2.208;
route 192.0.2.0/24 recursive 192.0.2.209; # <-- this one should be reachable 
route 192.0.2.0/24 recursive 192.0.2.210;
route 192.0.2.0/24 recursive 192.0.2.211;
route 192.0.2.0/24 recursive 192.0.2.212;
route 192.0.2.0/24 recursive 192.0.2.213;
route 192.0.2.0/24 recursive 192.0.2.214;
route 192.0.2.0/24 recursive 192.0.2.215;
route 192.0.2.0/24 recursive 192.0.2.216;
route 192.0.2.0/24 recursive 192.0.2.217;
route 192.0.2.0/24 recursive 192.0.2.218;
route 192.0.2.0/24 recursive 192.0.2.219;
route 192.0.2.0/24 recursive 192.0.2.220;
route 192.0.2.0/24 recursive 192.0.2.221;
route 192.0.2.0/24 recursive 192.0.2.222;
route 192.0.2.0/24 recursive 192.0.2.223;
route 192.0.2.0/24 recursive 192.0.2.224;
route 192.0.2.0/24 recursive 192.0.2.225;
route 192.0.2.0/24 recursive 192.0.2.226;
route 192.0.2.0/24 recursive 192.0.2.227;
route 192.0.2.0/24 recursive 192.0.2.228;
route 192.0.2.0/24 recursive 192.0.2.229;
route 192.0.2.0/24 recursive 192.0.2.230;
route 192.0.2.0/24 recursive 192.0.2.231;
route 192.0.2.0/24 recursive 192.0.2.232;
route 192.0.2.0/24 recursive 192.0.2.233;
route 192.0.2.0/24 recursive 192.0.2.234;
route 192.0.2.0/24 recursive 192.0.2.235;
route 192.0.2.0/24 recursive 192.0.2.236;
route 192.0.2.0/24 recursive 192.0.2.237;
route 192.0.2.0/24 recursive 192.0.2.238;
route 192.0.2.0/24 recursive 192.0.2.239;
route 192.0.2.0/24 recursive 192.0.2.240;
route 192.0.2.0/24 recursive 192.0.2.241;
route 192.0.2.0/24 recursive 192.0.2.242;
route 192.0.2.0/24 recursive 192.0.2.243;
route 192.0.2.0/24 recursive 192.0.2.244;
route 192.0.2.0/24 recursive 192.0.2.245;
route 192.0.2.0/24 recursive 192.0.2.246;
route 192.0.2.0/24 recursive 192.0.2.247;
route 192.0.2.0/24 recursive 192.0.2.248;
route 192.0.2.0/24 recursive 192.0.2.249;
route 192.0.2.0/24 recursive 192.0.2.250;
route 192.0.2.0/24 recursive 192.0.2.251;
route 192.0.2.0/24 recursive 192.0.2.252;
route 192.0.2.0/24 recursive 192.0.2.253;
route 192.0.2.0/24 recursive 192.0.2.254;
route 192.0.2.0/24 recursive 192.0.2.255;
}

I then set up a dummy device (and add it to OSPF so that it lands in birds 
routing table):

# ip link add dum0 type dummy
# ip addr add 192.0.2.209/28 dev dum0
# ip link set dev dum0 up
# ping -c1 192.0.2.209
PING 192.0.2.209 (192.0.2.209) 56(84) bytes of data.
64 bytes from 192.0.2.209: icmp_seq=1 ttl=64 time=0.022 ms

--- 192.0.2.209 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.022/0.022/0.022/0.000 ms

But then:

# birdc show route | grep '^192\.0\.2\.'
192.0.2.208/28     dev dum0 [ospf 04:57:58] * I (150/10) [14x.xxx.223.80]
192.0.2.0/24       unreachable [prefix_aggregation 04:57:57] * (200)
#

The 192.0.2.208/28 shows up in the routing table, so it IS reachable and hence 
at least one of the 192.0.2.0/24 route entries much be reachable. Yet, 
192.0.2.0/24 shows up as unreachable.



Thanks,
Luke






> Gesendet: Sonntag, 14. Januar 2024 um 00:24 Uhr
> Von: "Alexander Zubkov" <gr...@qrator.net>
> An: "Lukas Haase" <lukasha...@gmx.at>
> Cc: bird-users@network.cz
> Betreff: Re: Exporting a larger prefix if a smaller prefix is being exported
>
> Hi Lukas,
> 
> On Sun, Jan 14, 2024 at 6:23 AM Lukas Haase <lukasha...@gmx.at> wrote:
> >
> > Hi Alex,
> >
> > > Gesendet: Samstag, 13. Januar 2024 um 06:31 Uhr
> > > Von: "Alexander Zubkov" <gr...@qrator.net>
> > > An: "Lukas Haase" <lukasha...@gmx.at>
> > > Cc: bird-users@network.cz
> > > Betreff: Re: Exporting a larger prefix if a smaller prefix is being 
> > > exported
> > >
> > > Hi,
> > >
> > > You cannot do "direct" prefix aggregation to a lager prefix in Bird
> > > yet. But there are some ways to workaround it. You can define a static
> > > route with recursive nex-hop like 192.0.2.x, and filter it out when it
> > > is not reachable, but for any subprefix in /24 you would need to
> > > define 256 of such static routes. So it is up to you how practical it
> > > is.
> >
> > Interesting idea, this would be practical for me but I do not completely 
> > understand yet what you mean.
> > Which routes would I define and what would be the next hop ("like 
> > 192.0.2.x")?
> >
> > As an example, suppose the following prefixes are in my routing table and 
> > are directly or indirectly reachable: 192.0.2.208/28, 192.0.2.250/31, 
> > 192.0.2.184/29, 192.0.2.254/31, 192.0.2.176/29.
> >
> > Are you proposing?
> >
> > protocol static prefix_aggregation
> > {
> >   route 192.0.2.0/24 via 192.0.2.209;
> >   route 192.0.2.0/24 via 192.0.2.250;
> >   route 192.0.2.0/24 via 192.0.2.285;
> >   route 192.0.2.0/24 via 192.0.2.254;
> >   route 192.0.2.0/24 via 192.0.2.177;
> > }
> 
> Yes, something like that. But it needs to be "recursive" not "via".
> And your routes need not to be recursive already (for example iBGP
> makes such routes by default), because double recursion won't work.
> 
> >
> > If so, how do I avoid that 192.0.2.0/24 will be exported five times?
> 
> Yes, you'll have multiple similar routes. But if you do not have
> add-path on your BGP session, only one of them will be exported. Also
> in the recent version there is some aggregation support of same-net
> prefixes, it can be helpful here too.
> 
> > And how do I set up an export filter on "next-hop is not reachable"?
> 
> You need to check the corresponding attribute of the prefix. See the
> example later.
> 
> >
> > By the way, the sub-prefixes, would I just export via a filter like this?
> 
> Yes, this filter seems to cover the sub-prefixes. But not sure what is
> the nature of this question.
> 
> >
> > export filter {
> >     if (net ~ [192.0.2.0/24{25,32}]) then {
> >         accept;
> >     }
> >     reject;
> > }
> >
> 
> Here is a config example I can imagine, not tested it at all.
> Something like that works for us. But I would test it first that it
> correctly adds/reverts the "aggregated" prefix. It adds static
> prefixes in a separate table, but it can also be done in the main
> table and reachability tested in bgp export filter for example.
> 
> 
> ipv4 table aggr;
> 
> protocol static prefix_aggregation
> {
>   ipv4 { table aggr4; };
>   route 192.0.2.0/24 recursive 192.0.2.209;
>   ...
> }
> 
> protocol pipe pipe_aggr
> {
>   table master4;
>   peer table aggr;
>   export filter {
>     if (net ~ [192.0.2.0/24{25,32}]) then {
>       accept;
>     }
>     reject;
>   };
>   import filter {
>     if dest = RTD_UNREACHABLE then reject;
>     if (net = 192.0.2.0/24) then accept;
>     reject;
>   };
> }
> 
> 
> 
> > Thanks,
> > Luke
> >
> >
> >
> > > You can also make some external daemon watching your kernel routes
> > > and adding/deleting the aggregate route to the table.
> > >
> > > Regards,
> > > Alexander
> > >
> > > On Sat, Jan 13, 2024 at 2:05 AM Lukas Haase via Bird-users
> > > <bird-users@network.cz> wrote:
> > > >
> > > > Hi,
> > > >
> > > > Is is somehow possible to export a larger prefix if one or more 
> > > > sub-prefixes (subnets) are exported ... but also remove that prefix if 
> > > > no smaller subnet exist any more?
> > > >
> > > > Example: As soon as 192.0.2.44/32 or 192.0.2.208/28 (or any other 
> > > > prefix inside 192.0.2.0/24) is exported via eBGP, also export prefix 
> > > > 192.0.2.0/24. If no sub-prefixes are left, also remove 192.0.2.0/24 
> > > > from export.
> > > >
> > > > Background for my question is BGP. As is well known, the smallest 
> > > > prefix I can announce over eBGP is /24. I use bird as a border gateway 
> > > > and I announce various smaller prefixes via iBGP. The smaller prefixes 
> > > > will take precedence in my peering neighboring AS but the /24 is 
> > > > required to announce my network farther out.
> > > >
> > > > But why would I want that? Because there are actually two border 
> > > > gateways. If all internal links to one of these gateways breaks, the 
> > > > full subnet should not be announced any more (otherwise the traffic 
> > > > would be dropped). If at least one subnet is announced, I assume that 
> > > > the internal mesh is strong enough to find its way.
> > > >
> > > >
> > > > Thanks,
> > > > Luke
> > > >
> > > >
> > >
>

Reply via email to