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