Do not choose a route whose next hop cannot be reached (RFC 4271 §9.1.2.1)
Where routes go into the kernel, a route the kernel could not be given is no longer taken into the table: its next hop is no neighbor on any interface, or its prefix is a network the machine is itself on. Such a route used to be able to win selection and then leave its prefix without a route in the kernel, though another peer had one that worked. It is held aside the way an RPKI-invalid route is, and by the same means: judged on arrival against the interfaces as the kernel last described them, looked for in the table when they change, and taken from what is held when its next hop can be reached. The fib publishes the interfaces for this; the next hop is resolved once for an UPDATE and not for each of its routes. The lab has a phase, nexthops: FRR's better route with a next hop that is nowhere is held and BIRD's is installed, and they change places as an address comes and goes. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
1 parent
3d946c32ce
commit
f1d80c66df
15 files changed
+680
-63
No files matched your search
+14
-1
@@ -97,6 +97,19 @@ pub fn resolve(
|
||||
if interfaces.has_network_around(prefix) {
|
||||
return Err(Unresolved::OwnNetwork);
|
||||
}
|
||||
resolve_next_hop(interfaces, prefix.address_family(), next_hop, peer)
|
||||
}
|
||||
|
||||
/// The part of [`resolve`] that is the same for every route of IP version
|
||||
/// `routes` with one next hop from one peer: where the next hop is. For
|
||||
/// those who ask it of many such routes, and ask of each only whether it
|
||||
/// is for one of the machine's own networks.
|
||||
pub fn resolve_next_hop(
|
||||
interfaces: &Interfaces,
|
||||
routes: IpVersion,
|
||||
next_hop: Option<&NlriNextHop>,
|
||||
peer: Option<Neighbor>,
|
||||
) -> Result<Target, Unresolved> {
|
||||
let next_hop = next_hop.ok_or(Unresolved::Missing)?;
|
||||
let version = match next_hop {
|
||||
NlriNextHop::Ipv4(_) => IpVersion::Ipv4,
|
||||
@@ -105,7 +118,7 @@ pub fn resolve(
|
||||
// An IPv4 route may have an IPv6 next hop: that is how routes go over
|
||||
// a link with only IPv6 addresses (RFC 8950), and the kernel takes
|
||||
// such a route. The other way about means nothing.
|
||||
if version != prefix.address_family() && version == IpVersion::Ipv4 {
|
||||
if version != routes && version == IpVersion::Ipv4 {
|
||||
return Err(Unresolved::OtherFamily);
|
||||
}
|
||||
let direct = |gateway: IpAddr| {
|
||||
|
||||
Reference in new issue
Block a user