Dear BIRD dev-team and community,
This is a patch proposal spawned from the discussion in a previous mailing list
thread [0], regarding how to achieve automatic BGP peering establishment using
the IPv6 Neighbor Discovery mechanism.
Over the last few weeks, I worked on implementing the feature with the outline
Maria Matejka kindly provided.
As expected, it proved to be quite challenging, especially when it came to
integrate the peer discovery approach with the current dynamic BGP
implementation.
To briefly summarize the implemented automatic peering mechanism and added
capabilites:
- The ability for the RAdv protocol to receive and read incoming ICMPv6 RAs
was added.
- Route-like objects, containing RAs data are created, based on advertisments
detections. These are stored in a new kind of routing table.
- Lifetime of the objects in the table is determined by the ICMPv6 RA Router
Lifetime field. RA expiration will remove the object from the table.
- The discovery process is enabled only if a new neighbor discovery option is
enabled in the RAdv protocol configuration.
- A new channel was added to the BGP protocol called peers.
- When present in the BGP configuration, an export to this BGP channel
(allowed only in dynamic BGP) will trigger the spawn of a new session.
- Withdrawal the object from the peers routing table will trigger the
corresponding BGP session shutdown.
- An automatic BGP session can be made permanent via configuration with a
persist option in the peers channel.
To test the main functionality of this feature it I used multiple VMs linked by
a bridge with BIRD setup on all of them.
BGP session establishment is successful between all routers even with a very
minimal configuration.
I will provide an example, so you can also see the new configuration parameters
in action:
protocol device {
}
peer table nd_peers;
protocol radv radv1 {
peer {
table nd_peers;
};
interface "enp5s0" {
max ra interval 60;
min ra interval 20;
# Enable neighbor discovery on this interface
# When enabled, BIRD will parse incoming RAs and store router info
neighbor discovery yes;
};
}
protocol bgp bgp1 {
dynamic name "bgp_peer";
dynamic name digits 3;
local as 65000;
neighbor range fe80::/12 external; # Link-local range for BGP unnumbered
# Peers channel for importing peer discoveries and spawning sessions
peers {
# Interface for BGP session establishment
from "enp5s0";
# Persist sessions on route withdrawal
persist yes;
table nd_peers;
import all;
export all;
};
ipv4 {
import all;
export all;
};
ipv6 {
import all;
export all;
};
}
Of course, I have some concerns about some design choices and code
optimization, I tried to find the best solution that did not involve major
refactorings or moving code around and some comments on how to improve rough
edges from people more experienced on the current codebase would be really
appreciated.
Mostly, the two main points I am not entirely happy about are:
- How I handled the RAs staleness mechanism based on router lifetime.
I looked for it but there does not seem to be a per-route staleness
mechanism already in place, so I resorted to adding a check for expired entries
when the RAdv protocol timer is triggerd, which is not ideal.
- The mechanism to avoid spawning multiple sessions when both dynamic BGP and
this new feature are both configured.
For now, I try looking for BGP session with the same remote peer address
and give precedence to the ones spawned by the dynamic BGP mechanism, but I am
quite sure it is possible to find a better solution for this.
I tried to make the commit messages both informative and concise, but please
ask if something is unclear or missing.
I am still working on adding documentation and automated testing, but since I
think the discussion about the implemetation is more useful with actual code in
hand, I decided to send the main bulk of the patch right now and amend this
later along with changes addressing incoming reviews.
I hope you will appreciate the work done.
Best Regards,
Matteo
[0] https://bird.network.cz/pipermail/bird-users/2025-November/018482.html
Matteo Perin (4):
Nest: Add net_peer route type to track discovered peers
RAdv: Add neighbor discovery based on incoming RAs to RAdv proto
BGP: Move postponed socket reloop logic from start to start_locked to
achieve locking requirements
BGP: Add peers channel and sessions spawn on export to achieve
automatic peering
lib/net.c | 16 ++++
lib/net.h | 31 ++++++-
nest/config.Y | 3 +-
nest/proto.c | 2 +-
proto/bgp/attrs.c | 57 +++++++++++++
proto/bgp/bgp.c | 187 +++++++++++++++++++++++++++++++++++++++----
proto/bgp/bgp.h | 28 ++++++-
proto/bgp/config.Y | 15 +++-
proto/bgp/packets.c | 11 +++
proto/radv/config.Y | 3 +-
proto/radv/packets.c | 41 +++++++++-
proto/radv/radv.c | 163 ++++++++++++++++++++++++++++++++++++-
proto/radv/radv.h | 4 +
13 files changed, 533 insertions(+), 28 deletions(-)
--
2.43.0