-
Notifications
You must be signed in to change notification settings - Fork 2
fib
Pre-Alpha. This page describes behavior that may change.
The FIB pipeline in Ze takes BGP best-path output and programs the forwarding table. The pipeline is three plugins in a line: bgp-rib does per-protocol best-path tracking, sysrib (with unified Loc-RIB) does cross-protocol admin-distance selection, and a FIB backend programs the forwarding plane. Two FIB backends are available: fib-kernel programs the Linux kernel via netlink, and fib-vpp programs VPP's FIB via the GoVPP binary API. Both can run side by side.
This page covers the operational and configuration side. The deep architecture lives in route-selection in the main repo.
bgp-rib. The BGP RIB plugin runs best-path selection per prefix per family. When the best-path changes, it publishes a change event that the downstream plugins consume. This is also the plugin responsible for the BGP half of Graceful Restart: holding stale routes during a session restart, clearing them when EOR arrives.
sysrib. The system RIB is a cross-protocol selector. For a given prefix, it receives best-path changes from every source (BGP today, OSPF or IS-IS later) and picks the winner by admin distance. BGP's admin distance is 20 for eBGP and 200 for iBGP, the values every other routing daemon uses.
fib-kernel. The kernel programmer. It consumes sysrib selections and installs, updates, or withdraws routes in the kernel forwarding table via netlink. Routes are tagged with protocol RTPROT_ZE=250 so Ze's routes are distinguishable from static routes, DHCP routes, and other daemons' routes.
bgp {
peer upstream {
connection { remote { ip 10.0.0.1; } }
session {
asn { remote 65001; }
family { ipv4/unicast { prefix { maximum 1000000; } } }
}
process rib { receive [ update state ]; send [ update ]; }
}
}
fib-kernel, sysrib, and bgp-rib are internal plugins loaded automatically. bgp-rib is the only one you bind to peers. sysrib and fib-kernel consume events from the bus rather than from peers directly, so they do not appear in the process bindings.
Ze's best-path implementation follows RFC 4271 section 9.1.2 step by step. The order, and the specific comparisons:
| Step | Comparison | Source |
|---|---|---|
| 1 | Stale deprioritised | GR/LLGR stale level, threshold 2 (RFC 9494). |
| 2 | Highest LOCAL_PREF wins. | Default 100 if absent. |
| 3 | Shortest AS_PATH wins. | AS_SET counts as 1. |
| 4 | Lowest ORIGIN wins. | IGP (0), EGP (1), INCOMPLETE (2). |
| 5 | Lowest MED wins. | Same neighbour AS only. |
| 6 | eBGP over iBGP. | eBGP = peer ASN different from local ASN. |
| 7 | Lowest IGP cost to next-hop. | Not implemented (requires IGP integration). |
| 8 | Lowest router-id or ORIGINATOR_ID wins. | Numeric IP comparison (RFC 4271 / 4456). |
| 9 | Lowest peer address wins. | Final tiebreaker, numeric IP. |
Step 7 (IGP cost) is not implemented. Step 1 (GR/LLGR stale deprioritisation) runs before the rest so stale routes always lose to fresh routes, except when every candidate is stale.
A route that loses at step N gets tagged with the reason (lost-local-pref, lost-as-path-length, ...) so the operator can see why the route was not selected. ze show rib routes exposes the tag.
After admin-distance selection, sysrib resolves next-hops that are not directly connected. It walks the unified Loc-RIB by longest-prefix-match, up to a maximum depth of 8 levels, accumulating the IGP metric along the chain. The resolver tracks the dependents of each next-hop, so when a covering route changes (reachability or metric) every dependent prefix is re-evaluated by cascade. The accumulated IGP metric feeds best-path step 7.
Inspect the resolver tracking table with show nexthop-table. Each entry reports next-hop, resolved (bool), direct-nh (the directly-connected next-hop the chain resolves to), igp-metric, and the list of dependents prefixes.
When multiple best paths share the winner's effective priority and admin distance and metric, sysrib collects them into a single nexthop group rather than emitting separate single-path events. A group holds up to 128 members. FIB backends receive one event per prefix carrying the full ECMPPaths[] set, and program it as a multi-path forwarding entry.
Inspect the active groups with show ecmp-groups. Each entry reports prefix, family, and a paths array; each path carries next-hop, optional weight, and optional MPLS labels. Full ECMP tuning (hash policy, per-flow vs per-packet) is not implemented.
Beyond a plain destination and next-hop, the FIB pipeline carries richer route attributes end to end:
| Attribute | Meaning |
|---|---|
| Route type |
blackhole, unreachable, or prohibit for special-disposition routes. |
| Metric | Route metric / priority. |
| VRF table ID | Target routing table for policy-based and per-VRF installation. |
| MPLS labels | Label stack for labeled-unicast forwarding. |
| SRv6 SID | Segment Routing over IPv6 segment identifier. |
The kernel backend programs these via netlink (route type, metric, table, MPLS lwtunnel, SRv6 seg6). The VPP backend programs them through GoVPP with multi-path, route-type, metric, and table parity.
fib-kernel is a Linux-only netlink backend that installs, updates, and withdraws routes in the kernel forwarding table. A few operational notes worth knowing:
- Routes are tagged with
RTPROT_ZE=250. You can see them withip route show proto 250. - Stale-mark-sweep on startup:
fib-kernelmarks every pre-existingRTPROT_ZEroute as stale when it starts, then sweeps any routes that were not re-programmed within a timeout. This is the crash recovery path: if Ze dies and restarts, the kernel routes that Ze owned and that BGP has not re-computed are cleared. - External change monitoring:
fib-kernelsubscribes to netlink multicast and detects when an external process (another daemon, a human withip route) modifies a Ze-owned route. Depending on the policy, it either re-asserts its own view or logs the external change.
fib-p4 is an experimental P4 dataplane backend. It consumes the same sysrib output as fib-kernel but programs a P4 target instead of the Linux kernel. Experimental means you should not deploy it today.
ze cli -c "rib status" # bgp-rib state and counters
ze cli -c "rib routes received" # per-peer Adj-RIB-In
ze cli -c "rib routes sent" # per-peer Adj-RIB-OutFor the sysrib side:
ze cli -c "show rib" # cross-protocol selected routes
ze cli -c "show nexthop-table" # recursive next-hop resolver tracking
ze cli -c "show ecmp-groups" # active equal-cost multipath groupsFor the kernel side:
ip route show proto 250 # Routes installed by fib-kernel| Symptom | Cause | Fix |
|---|---|---|
Routes in rib status but not in the kernel |
fib-kernel not loaded, or not receiving the events. |
Check ze --plugins lists fib-kernel. |
| Routes in the kernel that should not be there | Another daemon is writing to RTPROT_ZE. |
Check the output of ip route show proto 250 and correlate with peer state. |
| Route selection unexpected | An earlier best-path step eliminated the route. |
ze show rib routes to see the per-route reason tag. |
The sysrib plugin selects the winning route across protocols using administrative distance. Lower values win. The defaults match the industry-standard Cisco/Junos values.
sysrib {
admin-distance {
connected 0;
static 10;
ebgp 20;
ospf 110;
isis 115;
ibgp 200;
}
}
| Leaf | Type | Default | Description |
|---|---|---|---|
connected |
uint8 | 0 |
Directly connected networks. |
static |
uint8 | 10 |
Static routes. |
ebgp |
uint8 | 20 |
External BGP routes. |
ospf |
uint8 | 110 |
OSPF routes. |
isis |
uint8 | 115 |
IS-IS routes. |
ibgp |
uint8 | 200 |
Internal BGP routes. |
Override a single value to change the selection priority. For example, to prefer iBGP over OSPF:
sysrib {
admin-distance {
ibgp 100;
}
}
The fib { kernel { } } block controls the Linux netlink backend that programs routes into the kernel forwarding table.
fib {
kernel {
flush-on-stop false;
sweep-delay 30;
}
}
| Leaf | Type | Default | Description |
|---|---|---|---|
flush-on-stop |
boolean | false |
Remove all Ze-installed routes when the plugin stops. When false, routes persist in the kernel after shutdown for graceful restart support. |
sweep-delay |
uint16 (seconds) | 30 |
Time to wait after startup before sweeping stale routes. Allows BGP reconvergence to refresh matching routes before orphans are removed. |
The fib { p4 { } } block configures the experimental P4 dataplane backend. It augments the same fib container and consumes sysrib output, but programs a P4 target via gRPC/P4Runtime instead of the Linux kernel.
fib {
p4 {
target 127.0.0.1:9559;
device-id 1;
flush-on-stop false;
}
}
| Leaf | Type | Default | Description |
|---|---|---|---|
target |
string | — | P4Runtime gRPC target address (host:port). |
device-id |
uint64 | 1 |
P4Runtime device ID. |
flush-on-stop |
boolean | false |
Remove all forwarding entries when the plugin stops. |
- BGP peers for the peer-level configuration.
-
Plugins for the
bgp-rib,sysrib,fib-kernel,fib-p4reference. - In-tree route selection for the full best-path detail.
Adapted from main/docs/architecture/route-selection.md.
Unreviewed draft. This wiki was authored in bulk and has not been reviewed. File corrections on the issue tracker.
- Overview
- YANG Model
- Editor Workflow
- Archive and Rollback
- System
- Interfaces
- VRRP
- BFD
- FIB
- OSPF
- IS-IS
- MPLS / LDP / RSVP-TE
- RSVP-TE
- SRv6
- Static Routes
- Policy Routing
- Firewall
- Traffic Control
- Class of Service
- L2TP/PPP
- PPPoE
- VPP Data Plane
- RPKI
- IPsec VPN
- TACACS+ AAA
- RADIUS AAA
- AS112 DNS
- Authorization
- Fleet
- BGP
- Starting and Stopping
- Show Commands
- Monitoring
- Flow Export
- DDoS Mitigation
- Anomaly Detection
- Health Checks
- Audit Trail
- Production Diagnostics
- Logging
- Operational Reports
- Healthcheck
- Self-Update
- Zero-Touch Provisioning
- MRT Analysis
- Upgrade and Restart
- Storage
- Policy
- Core
- Resilience
- Validation
- Capabilities
- Address Families
- Protocol
- Subsystems
- Infrastructure
- Route Server at an IXP
- Transit Edge with RPKI
- Public Looking Glass
- ExaBGP Migration Walkthrough
- FlowSpec Injection
- Chaos-Tested Peering
- AS Path Topology