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

+11 -2
View File
@@ -23,7 +23,7 @@ use crate::address::{Endpoint, PeerAddress, socket_text};
use crate::collision::Direction;
use crate::family::FamilySet;
use crate::fsm::Negotiated;
use crate::metrics::SESSIONS_ESTABLISHED;
use crate::metrics::{PEER_UP, SESSIONS_ESTABLISHED};
use crate::policy::PeerRole;
use crate::rpki::Subject;
use crate::sync::IgnorePoisonRw;
@@ -262,6 +262,9 @@ impl SessionRegistry {
.iter()
.map(|p| (p.name.clone(), DialState::Idle))
.collect();
for peer in &configured {
PEER_UP.with_label_values(&[&peer.name]).set(0);
}
Self {
inner: Arc::new(RwLock::new(HashMap::new())),
configured: Arc::new(configured),
@@ -306,6 +309,9 @@ impl SessionRegistry {
let peer = handle.peer;
self.inner.writing().insert(peer, handle.clone());
SESSIONS_ESTABLISHED.inc();
if let Some(name) = &handle.name {
PEER_UP.with_label_values(&[name]).set(1);
}
let _ = self.events.send(SessionEvent::Up(handle));
SessionGuard {
registry: self.clone(),
@@ -362,8 +368,11 @@ impl SessionRegistry {
fn remove(&self, peer: &PeerId) {
let removed = self.inner.writing().remove(peer);
if removed.is_some() {
if let Some(handle) = &removed {
SESSIONS_ESTABLISHED.dec();
if let Some(name) = &handle.name {
PEER_UP.with_label_values(&[name]).set(0);
}
let _ = self.events.send(SessionEvent::Down(*peer));
}
}