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>
270 lines
11 KiB
Markdown
270 lines
11 KiB
Markdown
# RFCs
|
|
|
|
Tracks which RFCs are implemented, partially implemented, or only represented
|
|
in the wire format layer.
|
|
|
|
**Legend**
|
|
- ✅ Implemented — functional end-to-end
|
|
- 🟡 Wire format only — parsed and serialised correctly, but not yet acted on
|
|
- ❌ Not implemented
|
|
|
|
---
|
|
|
|
## Core BGP
|
|
|
|
### RFC 4271 — A Border Gateway Protocol 4 (BGP-4)
|
|
https://datatracker.ietf.org/doc/html/rfc4271
|
|
|
|
The base protocol specification.
|
|
|
|
| Section | Description | Status |
|
|
|---------|-------------|--------|
|
|
| §4.1 | Message framing (marker, length, type) | ✅ |
|
|
| §4.2 | OPEN message | ✅ |
|
|
| §4.3 | UPDATE message (path attributes, NLRI, withdrawn routes) | ✅ |
|
|
| §4.4 | KEEPALIVE message | ✅ |
|
|
| §4.5 | NOTIFICATION message (all error codes and subcodes) | ✅ |
|
|
| §8 | FSM — passive (inbound) side: OpenSent → OpenConfirm → Established | ✅ |
|
|
| §8 | FSM — active (outbound) side: dial configured peers, exponential retry | ✅ |
|
|
| §6.2 | Bad Peer AS check against configured ASN | ✅ |
|
|
| §6.7 / RFC 4486 | Cease / Administrative Shutdown sent to every peer on SIGINT or SIGTERM | ✅ |
|
|
| §6.8 | Connection collision detection (BGP Identifier comparison, Cease / Connection Collision Resolution) | ✅ |
|
|
| §8.1.1 | Optional `CollisionDetectEstablishedState` (`collision_detect_established_state`) | ✅ |
|
|
| §6.2 | Bad BGP Identifier check (peer using our identifier, or 0.0.0.0) | ✅ |
|
|
| §9 | Decision process / best-path selection | ✅ |
|
|
| §9.1.2 | Best routes installed for forwarding (Linux kernel, over netlink), where the next hop is directly connected | ✅ |
|
|
| §9.1.2.1 | Routes with an unresolvable next hop excluded from selection; next hops resolved through other routes | ❌ (such a route can be chosen, and is then not installed) |
|
|
| §9 | Adj-RIB-In (per-peer table of received routes) | ✅ |
|
|
| §9 | Locally originated routes, advertised to all established peers | ✅ |
|
|
| §9 | Loc-RIB / Adj-RIB-Out for routes learned from peers (re-advertisement) | ❌ |
|
|
| §9.2 | Hold timer reset on any received message (not only KEEPALIVE) | ✅ |
|
|
|
|
---
|
|
|
|
## Capability and Session Extensions
|
|
|
|
### RFC 6793 — BGP Support for Four-Octet Autonomous System (AS) Number Space
|
|
https://datatracker.ietf.org/doc/html/rfc6793
|
|
|
|
| Feature | Status |
|
|
|---------|--------|
|
|
| `AS_TRANS` (23456) sentinel | ✅ |
|
|
| `FourByteAsn` capability advertisement and parsing | ✅ |
|
|
| 4-byte AS_PATH segment encoding/decoding via `ParserContext` | ✅ |
|
|
| 4-byte ASN negotiation in FSM | ✅ |
|
|
| AS4_PATH from a two-octet peer merged into AS_PATH on receipt (§4.2.3); one longer than AS_PATH ignored | ✅ |
|
|
|
|
### RFC 9774 — Deprecation of AS_SET and AS_CONFED_SET in BGP
|
|
https://datatracker.ietf.org/doc/html/rfc9774
|
|
|
|
| Feature | Status |
|
|
|---------|--------|
|
|
| Routes with an AS_SET in their path refused on import (`accept_as_sets` takes them) | ✅ |
|
|
| AS_SET never sent | ✅ |
|
|
|
|
### RFC 9072 — Extended Optional Parameters Length for BGP OPEN Message
|
|
https://datatracker.ietf.org/doc/html/rfc9072
|
|
|
|
| Feature | Status |
|
|
|---------|--------|
|
|
| Parsing extended-length OPEN (0xFF sentinel) | ✅ |
|
|
| Serialising extended-length OPEN when options exceed 255 bytes | ✅ |
|
|
|
|
### RFC 2918 — Route Refresh Capability for BGP-4
|
|
https://datatracker.ietf.org/doc/html/rfc2918
|
|
|
|
| Feature | Status |
|
|
|---------|--------|
|
|
| `RouteRefresh` capability advertisement | ✅ |
|
|
| `ROUTE-REFRESH` message type (5) framing | ✅ |
|
|
| AFI/SAFI payload parsing | ✅ |
|
|
| Acting on received ROUTE-REFRESH (re-advertising all local routes, regardless of the AFI/SAFI asked for) | ✅ |
|
|
|
|
### RFC 7313 — Enhanced Route Refresh Capability for BGP-4
|
|
https://datatracker.ietf.org/doc/html/rfc7313
|
|
|
|
| Feature | Status |
|
|
|---------|--------|
|
|
| `EnhancedRouteRefresh` capability wire format | 🟡 |
|
|
|
|
### RFC 4724 — Graceful Restart Mechanism for BGP
|
|
https://datatracker.ietf.org/doc/html/rfc4724
|
|
|
|
| Feature | Status |
|
|
|---------|--------|
|
|
| `GracefulRestart` capability wire format | 🟡 |
|
|
| Restart state and forwarding preserved across sessions | ❌ |
|
|
|
|
### RFC 9494 — Long-Lived Graceful Restart for BGP
|
|
https://datatracker.ietf.org/doc/html/rfc9494
|
|
|
|
| Feature | Status |
|
|
|---------|--------|
|
|
| `LongLivedGracefulRestart` capability wire format | 🟡 |
|
|
|
|
### RFC 8654 — Extended Message Support for BGP
|
|
https://datatracker.ietf.org/doc/html/rfc8654
|
|
|
|
| Feature | Status |
|
|
|---------|--------|
|
|
| `ExtendedMessage` capability wire format | 🟡 |
|
|
| Raising `BGP_MAX_MSG_LEN` to 65535 when negotiated | ❌ |
|
|
|
|
---
|
|
|
|
## Multiprotocol and NLRI
|
|
|
|
### RFC 2858 — Multiprotocol Extensions for BGP-4
|
|
https://datatracker.ietf.org/doc/html/rfc2858
|
|
|
|
| Feature | Status |
|
|
|---------|--------|
|
|
| `MultiProtocol` capability advertisement (IPv4 and IPv6 unicast) | ✅ |
|
|
| `MP_REACH_NLRI` path attribute (parse, serialise) | ✅ |
|
|
| `MP_UNREACH_NLRI` path attribute (parse, serialise) | ✅ |
|
|
| IPv4 and IPv6 next-hop encoding | ✅ |
|
|
|
|
### RFC 8950 — Advertising IPv4 Network Layer Reachability Information (NLRI) with an IPv6 Next Hop
|
|
https://datatracker.ietf.org/doc/html/rfc8950
|
|
|
|
| Feature | Status |
|
|
|---------|--------|
|
|
| `ExtendedNextHop` capability offered on sessions over IPv6 that carry IPv4 unicast, and used if the peer offers it | ✅ |
|
|
| IPv4 unicast routes sent and withdrawn in MP_REACH_NLRI / MP_UNREACH_NLRI with our IPv6 address as next hop | ✅ |
|
|
| IPv4 unicast routes received with an IPv6 next hop (global, or global and link-local) | ✅ |
|
|
| Such routes installed in the kernel (IPv4 route by way of an IPv6 neighbor) | ✅ |
|
|
| Other families than IPv4 unicast (VPN-IPv4, labelled) | ❌ |
|
|
| Sessions between link-local addresses (`fe80::1%eth0`), with link-local next hops | ✅ |
|
|
|
|
---
|
|
|
|
## Path Attributes and Communities
|
|
|
|
### RFC 1997 — BGP Communities Attribute
|
|
https://datatracker.ietf.org/doc/html/rfc1997
|
|
|
|
| Feature | Status |
|
|
|---------|--------|
|
|
| `COMMUNITIES` path attribute (parse, serialise) | ✅ |
|
|
| Attach to locally originated routes | ✅ |
|
|
|
|
### RFC 4360 — BGP Extended Communities Attribute
|
|
https://datatracker.ietf.org/doc/html/rfc4360
|
|
|
|
| Feature | Status |
|
|
|---------|--------|
|
|
| `EXTENDED_COMMUNITIES` path attribute (parse, serialise) | ✅ |
|
|
| AS-specific, IPv4-address-specific, opaque, route-target, route-origin subtypes | ✅ |
|
|
|
|
### RFC 8092 — BGP Large Communities Attribute
|
|
https://datatracker.ietf.org/doc/html/rfc8092
|
|
|
|
| Feature | Status |
|
|
|---------|--------|
|
|
| `LARGE_COMMUNITIES` path attribute (parse, serialise) | ✅ |
|
|
| Attach to locally originated routes | ✅ |
|
|
|
|
---
|
|
|
|
## Other Capabilities (Wire Format Only)
|
|
|
|
The following capabilities are parsed and serialised correctly but have no
|
|
functional behaviour implemented beyond that.
|
|
|
|
| RFC | Capability | Status |
|
|
|-----|-----------|--------|
|
|
| RFC 5291 | Outbound Route Filtering (ORF) | 🟡 |
|
|
| RFC 8205 | BGPsec | 🟡 |
|
|
|
|
---
|
|
|
|
## Error Handling
|
|
|
|
### RFC 9687 — BGP Send Hold Timer
|
|
https://datatracker.ietf.org/doc/html/rfc9687
|
|
|
|
| Feature | Status |
|
|
|---------|--------|
|
|
| `SendHoldTimer` error code (8) defined | ✅ |
|
|
| Send hold timer enforcement (a write that makes no progress ends the session) | ✅ |
|
|
|
|
---
|
|
|
|
## Route Security
|
|
|
|
### RFC 6811 — BGP Prefix Origin Validation
|
|
https://datatracker.ietf.org/doc/html/rfc6811
|
|
|
|
| Feature | Status |
|
|
|---------|--------|
|
|
| Validation states (valid, invalid, not found) for routes from external peers | ✅ |
|
|
| Invalid routes refused, per peer (`accept_rpki_invalid` to take them) | ✅ |
|
|
| Routes revalidated when the VRPs change, in both directions | ✅ |
|
|
| Validation of routes from internal peers and of originated routes | ❌ |
|
|
| Validity as a step of route selection (RFC 8097 communities) | ❌ |
|
|
|
|
### draft-ietf-sidrops-aspa-verification — BGP AS_PATH Verification Based on ASPA
|
|
https://datatracker.ietf.org/doc/draft-ietf-sidrops-aspa-verification/
|
|
|
|
Implemented from version 24 of the draft.
|
|
|
|
| Feature | Status |
|
|
|---------|--------|
|
|
| Upstream verification (routes from customers, peers, route servers and route server clients) | ✅ |
|
|
| Downstream verification (routes from providers) | ✅ |
|
|
| Per-peer role (`role`); paths of peers without one are not verified | ✅ |
|
|
| Invalid paths refused, per peer (`accept_aspa_invalid` to take them) | ✅ |
|
|
| Routes revalidated when the ASPAs change, in both directions | ✅ |
|
|
| Paths with an AS_SET invalid | ✅ |
|
|
| Verification on export | ❌ (learned routes are not exported yet) |
|
|
|
|
### RFC 9234 — Route Leak Prevention and Detection Using Roles in UPDATE and OPEN Messages
|
|
https://datatracker.ietf.org/doc/html/rfc9234
|
|
|
|
| Feature | Status |
|
|
|---------|--------|
|
|
| BGP Role capability sent for peers with a configured `role` | ✅ |
|
|
| Role Mismatch (OPEN Message Error, subcode 11) when the peer's role does not pair with ours, or it sends differing roles | ✅ |
|
|
| Strict mode (`require_role`) | ✅ |
|
|
| Only to Customer attribute: parse, serialise, treat-as-withdraw when malformed | ✅ |
|
|
| Ingress: marked routes from customers, route server clients and (unless marked by the peer itself) peers refused | ✅ |
|
|
| Ingress: routes from providers, peers and route servers marked | ✅ |
|
|
| Egress: originated routes to customers, peers and route server clients marked | ✅ |
|
|
| Egress: marked routes not sent to providers, peers or route servers | ❌ (learned routes are not exported yet) |
|
|
|
|
### RFC 8210 — The RPKI to Router Protocol, Version 1 (RFC 6810, version 0; draft-ietf-sidrops-8210bis, version 2)
|
|
https://datatracker.ietf.org/doc/html/rfc8210
|
|
|
|
Version 2 is implemented from version 23 of the draft.
|
|
|
|
| Feature | Status |
|
|
|---------|--------|
|
|
| Reset and serial queries, notifies, cache reset, incremental updates | ✅ |
|
|
| Refresh, retry and expire intervals; data dropped when it expires | ✅ |
|
|
| Version 2, with fallback to 1 and 0; several caches with failover | ✅ |
|
|
| ASPA PDU (version 2) | ✅ |
|
|
| Error Reports sent to the cache | ✅ |
|
|
| Version 2's ordering of PDUs enforced on what a cache sends | ❌ (any order is taken) |
|
|
| Transport over plain TCP | ✅ |
|
|
| Transport over SSH, TLS, TCP-MD5 or TCP-AO | ❌ |
|
|
| Router keys (BGPsec) | 🟡 read and ignored |
|
|
|
|
### RFC 7911 — Advertisement of Multiple Paths in BGP (ADD-PATH)
|
|
https://datatracker.ietf.org/doc/html/rfc7911
|
|
|
|
| Feature | Status |
|
|
|---------|--------|
|
|
| Capability negotiation per family and direction | ✅ |
|
|
| Receiving several routes for a prefix | ✅ |
|
|
| Sending several routes for a prefix | ❌ (path identifiers are sent; one route each) |
|
|
|
|
### RFC 4271 §9.1.2 / RFC 4486 / operational practice — import policy
|
|
|
|
| Feature | Status |
|
|
|---------|--------|
|
|
| Own AS in path refused (loop detection) | ✅ |
|
|
| Bogon prefixes and AS numbers, prefix length bounds, first-AS check | ✅ |
|
|
| Per-peer prefix and origin AS allow-lists | ✅ |
|
|
| Maximum prefixes with Cease / Maximum Number of Prefixes Reached and hold-down | ✅ |
|
|
|