Skip to content
Thomas Mangin edited this page Apr 8, 2026 · 5 revisions

Pre-Alpha. This page describes behavior that may change.

The FIB pipeline in Ze takes BGP best-path output and programs the Linux kernel forwarding table. The pipeline is three plugins in a line: bgp-rib does per-protocol best-path tracking, sysrib does cross-protocol admin-distance selection, and fib-kernel programs the kernel via netlink with the RTPROT_ZE=250 protocol identifier.

This page covers the operational and configuration side. The deep architecture lives in route-selection in the main repo.

The three plugins

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.

A minimal FIB setup

bgp {
    peer upstream {
        remote { ip 10.0.0.1; as 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.

Best-path selection

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.

ECMP

Ze has partial ECMP support. When multiple best paths with equal cost reach the sysrib, the FIB can install them as a multi-path entry. Full ECMP (load balancing, hash policy tuning, per-flow vs per-packet) is not implemented.

The fib-kernel plugin

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 with ip route show proto 250.
  • Stale-mark-sweep on startup: fib-kernel marks every pre-existing RTPROT_ZE route 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-kernel subscribes to netlink multicast and detects when an external process (another daemon, a human with ip route) modifies a Ze-owned route. Depending on the policy, it either re-asserts its own view or logs the external change.

The fib-p4 plugin (experimental)

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.

CLI and verification

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

For the kernel side:

ip route show proto 250             # Routes installed by fib-kernel

Troubleshooting

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.

Admin distance (sysrib)

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;
    }
}

Kernel FIB configuration (fib { kernel { } })

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.

P4 FIB configuration (fib { p4 { } }) (experimental)

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.

See also

Adapted from main/docs/architecture/route-selection.md.

Home

About

First Steps

Configuration

Operation

Interfaces

Plugins

Plugin Development

Chaos Testing

Blueprints

Development

Reference

Clone this wiki locally