Code health after review: docs, metrics, structure, one more fuzz target

What the code-health review found, and what a fuzz target written for it
found in its first seconds.

- A set of attributes with the same attribute twice is refused by the
  routing table. Its readers (the selection key, the path, the next hop)
  could each take a different one of the two. The decoder never lets one
  through; the new fuzz target `attrs` found that the table would.
- bgp_peer_up{peer}, to alert on a peer going away, and bgp_build_info.
  Every metric is there from the first scrape. Alerts for a peer down,
  hijack attempts and kernel errors are in the README.
- `bgp --check config` validates a configuration without starting, and
  `--version` says which build it is. CI runs the first on the example
  configuration, which a test now also parses with its commented fields
  put in; the example had to learn about the next hop check.
- Path attributes have a module of their own, packet::attributes,
  re-exported from packet::message as before.
- policy::From, which shadowed the trait, is RouteSource. The server's
  connection, dialer and fsm modules are private. Logging arguments live
  in the binary; the server library no longer depends on clap.
- One is_unicast_link_local (the standard library's) instead of two of
  our own; SelectionKey::origin(); one place where an Import is made.
- READMEs say what the daemon does today rather than what it did not do
  a year ago. Documentation links are checked in CI. Unused dependencies
  and bgp_web::serve are gone; the Docker build is --locked and does not
  ship the fuzz corpus.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Rayhaan JaufeerallyandClaude Fable 5.1 committed 2026-10-02 19:31:19 +02:00
1 parent 9ca86ede2f
commit 3d946c32ce
41 files changed
+1323 -1102

No files matched your search

+2 -6
View File
@@ -63,10 +63,6 @@ impl Unresolved {
}
}
fn is_link_local(address: &Ipv6Addr) -> bool {
address.segments()[0] & 0xffc0 == 0xfe80
}
/// The peer a route was learned from, as far as its next hop is concerned.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Neighbor {
@@ -152,14 +148,14 @@ pub fn resolve(
};
match *next_hop {
NlriNextHop::Ipv4(gateway) => direct(gateway.into()),
NlriNextHop::Ipv6(gateway) if is_link_local(&gateway) => on_peers_link(gateway),
NlriNextHop::Ipv6(gateway) if gateway.is_unicast_link_local() => on_peers_link(gateway),
NlriNextHop::Ipv6(gateway) => direct(gateway.into()),
// The global address if it is a neighbor; else the link-local one,
// which is there for exactly that case (RFC 2545 §3).
// Some put the link-local address, or nothing, where the global
// one goes, having no global one to give.
NlriNextHop::Ipv6WithLl { global, link_local }
if global.is_unspecified() || is_link_local(&global) =>
if global.is_unspecified() || global.is_unicast_link_local() =>
{
on_peers_link(link_local)
}