Files
ferrix/docs/RFCs.md
T
Rayhaan JaufeerallyandClaude Fable 5.1 9ca86ede2f Harden import, the kernel task and the RTR client after review
Three independent reviews (hijack resistance, reliability, code health)
of the whole tree. This is what they found that could let a bad route in
or take the daemon down.

Hijacks:
- A route had two paths on a two-octet session, AS_PATH and AS4_PATH,
  read in two places by two rules. A peer could make the origin checked
  on import differ from the one checked at revalidation, and get an
  RPKI-invalid route into the table. AS4_PATH is now merged into AS_PATH
  once, on receipt (RFC 6793 §4.2.3), and nothing else knows of it.
- The next hop is judged on import: it must be usable, agreed on
  (RFC 8950), and by default the peer itself.
- Our own originated prefixes are not taken from other networks.
- A route for a network the machine is on is never put in the kernel.
- Paths with an AS_SET are refused (RFC 9774).
- A configured peer gets one session, not one per BGP Identifier.
- More IPv6 special-purpose prefixes are bogons.

Reliability:
- A batch of requests the kernel refused could overflow the netlink
  socket and end the daemon. The socket has room now, a lost answer or a
  silent kernel means asking what is there, and neither is fatal.
- Working the routes out again within the grace period after a restart
  no longer drops the routes being kept.
- That work can no longer be put off for ever by interface changes.
- Peers whose sessions keep failing are slowed down.
- Unused attribute sets are swept when they pile up, not only each
  minute.
- Log lines a peer can cause are said once in a while.
- An RTR answer is bounded in size and time; data cannot expire between
  two refreshes.
- The shard of a key is taken from a stirred hash: neighbouring bits of
  the hash proved alike for prefixes in a row. The test that showed it,
  failing one run in sixteen, is deterministic now.

The lab has a phase, hijacks, in which FRR tries the first three.
route::apply is a struct with methods instead of nested closures, and
the kernel task's loop is shorter.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-02 19:13:40 +02:00

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 | ✅ |