Compare

BGP implementation comparison

A feature comparison of open source BGP daemon implementations. This page keeps the BGP-specific matrix separate from the full Network OS comparison. It also carries an OSPF table against FRR and BIRD, the two other daemons here that implement it.

Disclaimer and evidence: this comparison was generated with AI assistance and is provided for informational purposes only. All listed projects are under active development and their capabilities change over time. Verify current features against each project's own documentation before making decisions. Rows should be read as evidence-backed advice rather than marketing: code paths link to upstream source where the site can map them, official feature pages are preferred when source links are not practical, and No or Partial means the cited evidence did not support a stronger claim. Corrections and updates are welcome via the issue tracker.

Overview

Ze BIRD 3 BIRD 2 FRR OpenBGPd GoBGP bio-rd ExaBGP RustyBGP rustbgpd freeRtr
Language Go C C C C Go Go Python Rust Rust Java
License AGPL 3.0 GPL 2.0+ GPL 2.0+ GPL 2.0 ISC Apache 2.0 Apache 2.0 BSD 3-Clause Apache 2.0 MIT Free
Primary interface CLI, SSH, REST, gRPC CLI CLI CLI CLI gRPC gRPC CLI, API gRPC gRPC CLI
First release 2026 2024 1998 2017 2004 2014 2018 2010 2019 2026 2012
Multithreaded ✓ ✓ ✕ ✕ ✓ ✓ ✓ ✕ ✓ ✓ ✓
Multithread model Goroutines Cooperative threads -- -- 3-process Goroutines Goroutines -- Multi-core Tokio Per-peer
Plugin architecture ✓ ✕ ✕ ✕ ✕ ✕ ✕ ✕ ✕ ✕ ✕
YANG-modeled config ✓ ✕ ✕ ∿ ✕ ✕ ✕ ✕ ✕ ✕ ✕

Address Families

AFI/SAFI Ze BIRD 3 BIRD 2 FRR OpenBGPd GoBGP bio-rd ExaBGP RustyBGP rustbgpd freeRtr
IPv4 Unicast ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓
IPv6 Unicast ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓
IPv4 Multicast ✓ ✓ ✓ ✓ ✕ ✓ ✕ ✕ ✕ ✕ ✓
IPv6 Multicast ✓ ✓ ✓ ✓ ✕ ✓ ✕ ✕ ✕ ✕ ✓
IPv4 Labeled Unicast ✓ ✕ ✕ ✓ ✕ ✓ ✕ ✓ ✕ ✕ ✓
IPv6 Labeled Unicast ✓ ✕ ✕ ✓ ✕ ✓ ✕ ✓ ✕ ✕ ✓
VPNv4 (RFC 4364) ✓ ✓ ✓ ✓ ✓ ✓ ✕ ✓ ✕ ✕ ✓
VPNv6 ✓ ✓ ✓ ✓ ✓ ✓ ✕ ✓ ✕ ✕ ✓
L2VPN EVPN (RFC 7432) ✓ ✓ ✓ ✓ ✕ ✓ ✕ ✓ ✕ ✕ ✓
L2VPN VPLS ✓ ✕ ✕ ✕ ✕ ✓ ✕ ✓ ✕ ✕ ✓
IPv4 FlowSpec (RFC 8955) ✓ ✓ ✓ ✓ ✓ ✓ ✕ ✓ ✕ ✓ ✓
IPv6 FlowSpec ✓ ✓ ✓ ✓ ✓ ✓ ✕ ✓ ✕ ✓ ✓
VPN FlowSpec ✓ ✕ ✕ ✕ ✕ ✓ ✕ ✕ ✕ ✕ ✓
BGP-LS (RFC 7752) Decode (40 TLVs) ✕ ✕ ✕ ✕ ✓ ✕ Decode ✕ ✕ ✓
SR Policy ✓ ✕ ✕ ✕ ✕ ✓ ✕ ✕ ✕ ✕ ∿
IPv4/IPv6 MUP ✓ ✕ ✕ ✕ ✕ ✓ ✕ ✕ ✕ ✕ ✓
IPv4/IPv6 MVPN Decode ✕ ✕ ✕ ✕ ✕ ✕ ✕ ✕ ✕ ✓
IPv4 RTC (RFC 4684) Decode ✕ ✕ ✕ ✕ ✕ ✕ ✓ ✕ ✕ ✓

Core Protocol

Feature Ze BIRD 3 BIRD 2 FRR OpenBGPd GoBGP bio-rd ExaBGP RustyBGP rustbgpd freeRtr
RFC 4271 FSM ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓
4-byte ASN (RFC 6793) ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓
AS notation, asplain/asdot/asdot+ (RFC 5396) ✓ ? ? ✓ ? ? ? ? ? ? ?
Capability negotiation ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓
Route Refresh (RFC 2918) ✓ ✓ ✓ ✓ ✓ ✓ ✕ ✓ ✕ ✓ ✓
Enhanced Route Refresh (RFC 7313) ✓ ✓ ✓ ✓ ✓ ✕ ✕ ✓ ✕ ✓ ✓
Graceful Restart (RFC 4724) ✓ ✓ ✓ ✓ ✓ ✓ ✕ ∿ ✕ ✓ ✓
Long-Lived GR (RFC 9494) ✓ ✓ ✓ ∿ ✕ ✓ ✕ ✕ ✕ ✓ ✓
Notification GR (RFC 8538) ✕ ✕ ✕ ✕ ✓ ✓ ✕ ✕ ✕ ✓ ✕
Startup convergence hold (update-delay) ✓ ? ? ? ? ? ? ? ? ? ?
Add-Path (RFC 7911) ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ Rx only ✓ ✓
Paths-Limit (draft-abraitis) ✓ ✕ ✕ ✓ ✕ ✕ ✕ ✓ ✕ ✕ ✕
BFD strict mode (draft-ietf-idr-bgp-bfd-strict-mode) ✓ ? ? ✓ ? ? ? ? ? ? ?
Extended Messages (RFC 8654) ✓ ✓ ✓ ✓ ✓ ✓ ✕ ✓ ✕ ✓ ✓
Extended Nexthop (RFC 8950) ✓ ✓ ✓ ✓ ✓ ✓ ✕ ✓ ✕ ✓ ✓
Route Reflector (RFC 4456) ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✕ ✕ ✓ ✓
Confederation (RFC 5065) ✕ ✓ ✓ ✓ ✕ ✓ ✕ ✕ ✕ ✕ ✓
Admin Shutdown (RFC 8203) ✓ ✓ ✓ ✓ ✓ ✓ ∿ ✓ ✕ ✓ ∿
BGP Roles (RFC 9234) ✓ ✓ ✓ ✕ ✓ ✕ ✓ ✕ ✕ ✕ ∿
Prefix Limit (RFC 4486) ✓ ✓ ✓ ✓ ✓ ✓ ✕ ✕ ✕ ✓ ✓

AS notation: an AS number is accepted in any of the three RFC 5396 notations everywhere in the configuration and in every command, and bgp as-notation picks the one Ze prints. FRR carries the same choice as bgp asnotation.

BFD strict mode: the capability holds a BGP session out of Established until the BFD session to that neighbor is Up, so a session never forms across a link BFD cannot cross. FRR carries it as neighbor <peer> bfd strict. The other daemons here were not checked for it.

Cross-Protocol Redistribute

Ze advertises locally-originated routes from non-BGP protocols (connected, static, L2TP, IS-IS, OSPF) into BGP via the redistribute-orchestrator plugin. Operators enable it per-destination and per-source via redistribute { destination <proto> { import <source> { family [...]; } } }. The same config block also drives the intra-BGP IngressFilter ACL when the source is ibgp / ebgp. Per-peer NEXT_HOP substitution (nhop self) is automatic; explicit producer-supplied NEXT_HOP is passed through verbatim.

The block is the whole configuration, which is the behavior FRR and BIRD have. import bgp names ze's own Loc-RIB and derives the peer-to-plugin delivery it depends on, so no second binding is written by hand. A consumer that registers after a producer emitted is replayed that producer's current set, so the outcome does not depend on which protocol started first.

IS-IS meshes with BGP in both directions, matching the vendor IGP-BGP mutual-redistribution operators expect. IPv6 rides the same single-topology SPF tree -- matching one other implementation's single-topology IS-IS default (that implementation also offers RFC 5120 Multi-Topology, which Ze does not yet implement).

OSPFv2 meshes with BGP in both directions like IS-IS, exports OSPF routes into BGP, and injects connected/static/BGP routes as Type 5 AS-External LSAs. Ze also implements stub, totally-stubby, and NSSA areas (RFC 3101) with Type 7 origination, translator election, and Type 7 to Type 5 translation. The RFC 3101 §2.4 border-router default is originated into every attached NSSA in both address families with no operator leaf, and the same install-side gates on a received Type 7 default (P-bit clear, summary import suppressed) apply to both; FRR gates the same origination on default-information-originate. Per-interface authentication covers simple password, keyed-MD5 (RFC 2328), HMAC-SHA (RFC 5709), and the RFC 7474 extended-sequence variant, with key chains for hitless rotation and sequence-number replay protection.

Policy & Route Manipulation

Ze takes a programmable approach to policy: external plugin filters manipulate routes via filter { import [...] export [...] } chains using named filter instances or explicit <plugin>:<filter> references. Filters chain as piped transforms (accept/reject/modify) with delta-only output. RFC-mandated checks run as default filters that can be selectively overridden. Built-in filter plugins shipped with Ze include prefix-list matching (ge/le bounds), AS-path regex filtering, community presence matching (standard/large/extended), route attribute modification (local-preference, MED, origin, next-hop, AS-path prepend), community tag/strip, and RFC 9234 role enforcement.

Feature Ze BIRD 3 BIRD 2 FRR OpenBGPd GoBGP bio-rd ExaBGP RustyBGP rustbgpd freeRtr
Prefix matching (ge/le) ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✕ ∿ ✓ ✓
AS-path regex ✓ ✓ ✓ ✓ ✓ ✓ ✕ ✕ ✕ ✓ ✓
Standard communities ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓
Extended communities ✓ ✓ ✓ ✓ ✓ ✓ ✕ ✓ ✕ ✓ ✓
Large communities (RFC 8092) ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✕ ✓ ✓
Community add/remove/replace ✓ ✓ ✓ ✓ ✓ ✓ ✓ API ✕ ✓ ✓
MED manipulation (set/inc/dec) ✓ ✓ ✓ ✓ ✓ ✓ ✓ API ✕ ✓ ✓
LOCAL_PREF set/inc/dec ✓ ✓ ✓ ✓ ✓ ✓ ✓ API ✕ ✓ ✓
AS-path length filter ✓ ✓ ✓ ✕ ✓ ✕ ✕ ✕ ✕ ✕ ✕
AS-path prepend ✓ ✓ ✓ ✓ ✓ ✓ ✓ API ✕ ✓ ✓
Next-hop set/self ✓ ✓ ✓ ✓ ✓ ✓ ✓ API ✕ ✓ ✓
RPKI validation match ✓ ✓ ✓ ✓ ✓ ✓ ✕ ✕ ✓ ✓ ✓
Neighbor/peer matching ✓ ✓ ✓ ✓ ✓ ✓ ✕ ✕ ✕ ✓ ✓
Named policy definitions Plugin ✓ ✓ ✓ ✓ ✓ ✓ ✕ ∿ ✓ ✓
Policy chaining ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✕ ✕ ✓ ✓
Custom filter language ✕ ✓ ✓ ✕ ✓ ✕ ✕ ✕ ✕ ✕ ✕
External process policy ✓ ✕ ✕ ✕ ✕ ✕ ✕ ✓ ✕ ✕ ✕
Plugin-based policy ✓ ✕ ✕ ✕ ✕ ✕ ✕ ✕ ✕ ✕ ✕

Security

Feature Ze BIRD 3 BIRD 2 FRR OpenBGPd GoBGP bio-rd ExaBGP RustyBGP rustbgpd freeRtr
TCP MD5 (RFC 2385) ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✕ ✓ ✓
TCP-AO (RFC 5925) ✕ ✕ ✕ ✕ ✕ ✕ ✕ ✕ ✕ ✕ ✕
GTSM / TTL Security ✓ ✓ ✓ ✓ ✓ ✓ ∿ ✓ ✕ ✓ ✓
RPKI/RTR (RFC 6810/8210) ✓ ✓ ✓ ✓ ✓ ✓ ✕ ✕ ✓ ✓ ✓
ASPA verification ✓ ✓ ✓ ✕ ✓ ✕ ✕ ✕ ✕ ✓ ✕
Private AS removal ✓ ✓ ✓ ✓ ✓ ✓ ✕ ✕ ✕ ✓ ✓
Privilege separation ✕ ✕ ✕ ✕ ✓ ✕ ✕ ✕ ✕ ✕ ✕
TACACS+ AAA (RFC 8907) ✓ ✕ ✕ ✓ ✕ ✕ ✕ ✕ ✕ ✕ ✓
Memory-safe language ✓ ✕ ✕ ✕ ✕ ✓ ✓ ✓ ✓ ✓ ✓

Monitoring & Observability

Feature Ze BIRD 3 BIRD 2 FRR OpenBGPd GoBGP bio-rd ExaBGP RustyBGP rustbgpd freeRtr
Prometheus metrics ✓ ✕ ✕ ✓ ✕ ✓ ✓ ✕ ✕ ✓ ✕
Structured logging (JSON) ✓ ✕ ✕ ✕ ✕ ✕ ✓ ✕ ✕ ✓ ✕
BMP (RFC 7854) ✓ ✓ ✓ ✓ ✕ ✓ ✓ ✕ ∿ ✓ ✓
MRT dump (RFC 6396) ✓ ✓ ✓ ✓ ✓ ✓ ✕ ✕ ✓ ✓ ✓
Writes a pcap of its BGP sessions ✓ ✕ ✕ ✕ ✕ ✕ ✕ ✕ ✕ ✕ ✕
Decodes a pcap of a BGP session ✓ ✕ ✕ ✕ ✕ ✕ ✕ ✕ ✕ ✕ ✕
Flow export (sFlow/NetFlow/IPFIX) ✓ ✕ ✕ ✕ ✕ ✕ ✕ ✕ ✕ ✕ ✕
Streaming route events ✓ ✕ ✕ ✕ ✕ ✓ ✓ ✓ ✕ ✓ ✕
JSON event protocol ✓ ✕ ✕ ✕ ✕ ✕ ✕ ✓ ✕ ✕ ✕
Built-in DNS resolver ✓ ✕ ✕ ✕ ✕ ✕ ✕ ✕ ✕ ✕ ✕
Static DNS name-servers ✓ ✕ ✕ ✓ ✕ ✕ ✓ ✓ ✕ ✕ ✕
Built-in PeeringDB/IRR/Cymru ✓ ✕ ✕ ✕ ✕ ✕ ✕ ✕ ✕ ✕ ✕
Unified operational reports ✓ ∿ ∿ ∿ ∿ ✕ ✕ ✕ ✕ ✕ ∿
SNMP agent (AgentX/MIB) ✕ ✕ ✕ ✓ ✕ ✕ ✕ ✕ ✕ ✕ ✓

Writes and decodes a pcap: show capture-raw dump bgp pcap writes the recorded messages as a pcap Wireshark dissects as BGP, and ze bgp decode pcap reads one back, reassembling each TCP direction first. The reader takes a tcpdump capture too, so an operator decodes a colleague's file without ze having produced it. ExaBGP decodes hexadecimal from standard input, which ze bgp decode - now matches, but it reads no pcap. The other ten daemons are marked No because none documents a pcap writer or reader of its own; an operator captures with tcpdump and reads the file in Wireshark.

Most BGP daemons expose operational issues through a mix of per-command output rather than a single aggregated view. Ze provides a cross-subsystem report bus: any subsystem can push warnings (state-based) or errors (event-based) onto a single place, and ze show warnings / ze show errors return the aggregate as structured JSON. The login banner reads the same source, so nothing is silently hidden.

SNMP is a deliberate non-goal, not a gap: FRR and freeRtr both expose legacy AgentX/MIB agents, but Ze's operational surface (Prometheus, gNMI, gRPC, structured JSON events) already covers what those MIBs would carry, without maintaining a second protocol stack to do it.

API & Programmability

Feature Ze BIRD 3 BIRD 2 FRR OpenBGPd GoBGP bio-rd ExaBGP RustyBGP rustbgpd freeRtr
gNMI ✓ ✕ ✕ ∿ ✕ ✕ ✕ ✕ ✕ ✕ ✕
gRPC API ✓ ✕ ✕ ∿ ✕ ✓ ✓ ✕ ✓ ✓ ✕
REST API ✓ ✕ ✕ ∿ ✕ ✕ ✕ ✕ ✕ ∿ ✕
YANG model ✓ ✕ ✕ ∿ ✕ ✕ ✕ ✕ ✕ ✕ ✕
Register-once operator surfaces ✓ ✕ ✕ ∿ ✕ ✕ ✕ ✕ ✕ ✕ ∿
CLI tool ✓ ✓ ✓ ✓ ✓ ✓ ∿ ✓ ✕ ✓ ✓
CLI JSON output ✓ ✕ ✕ ✓ ✓ ✓ ✕ ✓ ✕ ✓ ✕
Runtime route injection ✓ ✕ ✕ ✕ ✕ ✓ ✕ ✓ ✓ ✓ ✓
Hot reconfiguration (no restart) ✓ ✓ ✓ ✓ ✓ ✓ ∿ ✓ ✕ ✓ ✓
Embeddable library ✕ ✕ ✕ ✕ ✕ ✓ ✓ ✕ ✕ ✕ ✕
Plugin SDK ✓ ✕ ✕ ✕ ✕ ✕ ✕ ✕ ✕ ✕ ✕
External process protocol ✓ ✕ ✕ ✕ ✕ ✕ ✕ ✓ ✕ ✕ ✕
MCP (Model Context Protocol) server ✓ ✕ ✕ ✕ ✕ ✕ ✕ ✕ ✕ ✕ ✕
SSH CLI access ✓ ✕ ✕ ✕ ✕ ✕ ✕ ✕ ✕ ✕ ✓

Ze's register-once row means a command, config node, plugin, RPC, or event can feed the CLI, web workbench, REST/gRPC, MCP, generated docs, completion, authorization, and audit paths. FRR has partial YANG/API evidence. freeRtr has integrated CLI, NETCONF, and help generation, but not the same all-surface pipeline in the inspected sources.

Operations

Feature Ze BIRD 3 BIRD 2 FRR OpenBGPd GoBGP bio-rd ExaBGP RustyBGP rustbgpd freeRtr
Crash capture (syslog + file) ✓ ✕ ✕ ✕ ✕ ✕ ✕ ✕ ✕ ✕ ✕
Config error diagnostics ✓ ✕ ✕ ✕ ✕ ✕ ∿ ✕ ✕ ✓ ∿
Runtime health monitoring ✓ ✕ ✕ ✕ ✕ ✕ ✕ ✕ ✕ ✕ ✕
Pre-start readiness checks ✓ ✕ ✕ ✕ ✕ ✕ ✕ ✕ ✕ ✕ ✕
Product doctor/debug workflow ✓ ✕ ✕ ✕ ✕ ✕ ✕ ✕ ✕ ✕ ∿
Docker image ✓ ✓ ✓ ✓ ✕ ✓ ✓ ✓ ✕ ✓ ✓
Fuzz testing ✓ ✕ ✕ ✕ ✕ ✕ ✓ ✕ ✕ ✓ ✕
Interop test suite ✓ ✕ ✕ ✕ ✕ ✕ ∿ ✕ ✕ ✓ ✓
Static routes (ECMP+BFD) ✓ ✓ ✓ ✓ ✓ ✕ ✕ ✕ ✕ ✕ ✓
Policy-based routing (PBR) ✓ ✕ ✕ ✓ ✕ ✕ ✕ ✕ ✕ ✕ ✓
FIB/kernel integration ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✕ ✕ ✕ ✓
Sysctl management ✓ ✕ ✕ ∿ ∿ ✕ ✕ ✕ ✕ ✕ ✕
Route server mode ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✕ ✕ ✓ ✓
Dynamic neighbors ✓ ✓ ✓ ✓ ✕ ✓ ✕ ✕ ✓ ✕ ✓
Looking glass ✓ ✓ ✓ ✕ ✓ ✕ ✓ ✕ ✕ ✓ ✓
BFD integration ∿ ✓ ✓ ✓ ✕ ✕ ✕ ✕ ✕ ✕ ✓
Firewall (nftables) ✓ ✕ ✕ ✓ ✓ ✕ ✕ ✕ ✕ ✕ ✓
Config commit/rollback (candidate + active) ✓ ✕ ✕ ✕ ✕ ✕ ✕ ✕ ✕ ✕ ✕

Update groups: Ze automatically groups peers by encoding context and builds each UPDATE once per group, fanning out the wire bytes to all members. No configuration needed -- one other implementation in this table requires explicit peer-group assignment for the same optimization.

Best-Path Selection

ExaBGP does not perform best-path selection -- it forwards all received routes to external processes and injects routes from them. It is a route injector/receiver, not a router.

Step Ze BIRD 3 BIRD 2 FRR OpenBGPd GoBGP bio-rd ExaBGP RustyBGP rustbgpd freeRtr
LOCAL_PREF ✓ ✓ ✓ ✓ ✓ ✓ ✓ N/A ✓ ✓ ✓
AS-path length ✓ ✓ ✓ ✓ ✓ ✓ ✓ N/A ✓ ✓ ✓
ORIGIN ✓ ✓ ✓ ✓ ✓ ✓ ✓ N/A ✓ ✓ ✓
MED ✓ ✓ ✓ ✓ ✓ ✓ ✓ N/A ✓ ✓ ✓
eBGP over iBGP ✓ ✓ ✓ ✓ ✓ ✓ ✓ N/A ✓ ✓ ✓
CLUSTER_LIST length ✓ ✓ ✓ ✓ ✓ ✓ ✓ N/A ✕ ✓ ✓
ORIGINATOR_ID ✓ ✓ ✓ ✓ ✓ ✓ ✓ N/A ✕ ✓ ✓
Stale route demotion (GR) ✓ ✓ ✓ ✓ ✓ ✓ ✕ N/A ✕ ✓ ✓
RPKI preference ✓ ✓ ✓ ✓ ✓ ✓ ✕ N/A ✓ ✓ ✓
AIGP ∿ ✕ ✕ ✓ ✕ ✓ ✕ N/A ✕ ✕ ✓
IGP cost to next-hop ✓ ✓ ✓ ✓ ✓ ✕ ✕ N/A ✕ ✕ ✓
Recursive next-hop ✓ ✓ ✓ ✓ ✓ ✕ ✕ N/A ✕ ✕ ✓
Multipath/ECMP ✓ ✓ ✓ ✓ ✓ ✓ ✓ N/A ✕ ∿ ✓

OSPF Standards Coverage

The tables above compare BGP. This one compares OSPF, against the two daemons that also implement it natively. Ze, FRR and BIRD are the whole population here: the other implementations in this table speak BGP only.

Version basis. Ze at commit 35f84e060. FRR at release tag frr-10.7.1 (2026-08-31). BIRD 2.19.2 and BIRD 3.3.2 (both 2026-07-30), which carry an identical OSPF standards list, so one column serves both.

What each column asserts. The three columns are not judged alike, so no cell here says a bare "yes".

A Ze cell states what the code does with the value, in three grades. Originates and consumes means Ze builds it, parses it on receipt, and something acts on the parsed value. Originates means built and parsed, with no consumer beyond display. No means no producer exists.

An FRR or BIRD cell names the evidence: the configuration command, or the source file that implements it, at the version above. That is what was checked. Neither daemon was run, and no cell here claims interop.

RFC Ze FRR 10.7.1 BIRD 2.19.2 / 3.3.2
8362 OSPFv3 Extended LSAs Originates 3 of the 7 LSA types, and only under segment routing. Decoded on receipt only to read Prefix-SIDs. No consumer in SPF. Non-conformant on the wire, see the note below ✕ ✕
8666 OSPFv3 Segment Routing Originates and consumes: installs labels to the MPLS FIB. 3 MUST-level gaps declared ✕ ✕
8665 OSPFv2 Segment Routing Originates and consumes: installs labels. 14 MUST-level gaps declared ✓ ✕
5286 Loop-Free Alternate Originates nothing on the wire, correctly. Computes LFA and TI-LFA, and the backup next hops reach the kernel with RTNH_F_LINKDOWN TI-LFA only: fast-reroute ti-lfa, and the docs say it requires a Segment Routing configuration. FRR's RFC 5286 code is ospfd does not use. isisd/isis_lfa.c ✕
7684 Extended Prefix and Link Originates and consumes: Segment Routing reads the prefix SIDs. A received Adj-SID is decoded and discarded ✓ ✕
7770 Router Information Originates and consumes: a remote SRGB read from these LSAs drives label computation ✓ Listed as supported, but dormant: ospf_originate_ri_lsa() is commented out at its only call site, and lsa_validate_ri says "we do not really process RI LSAs"
3630 and 5392 Traffic Engineering Originates both. The TE database feeds show ospf te-database and metrics. No CSPF or admission consumer reads it: LookupLink has no non-test caller ✓ ✕
5250 Opaque LSAs Originates and consumes, with a registry other features register consumers into ✓ Carries and floods them, including unknown types, and originates none
3623 and 5187 Graceful Restart Originates and consumes, both versions: Grace-LSA out, helper in, with self-LSA suppression, install suppression and FIB retention ✓ ✓
5443 LDP-IGP Synchronization Originates and consumes: an LDP session event substitutes the advertised metric, and the Router-LSA is re-originated ✓ ✕
4577 OSPF as PE/CE ✕ ✕ The DN bit only: vpn pe in the grammar, consumed in rt.c. No sham link in its interface-type set either

Where the open ground is. RFC 8362 and RFC 8666 travel together, because OSPFv3 Segment Routing is defined over the Extended LSAs. Neither FRR nor BIRD implements either, so this is the one part of the table where Ze is alone.

A note on RFC 8362, because the row above says less than it looks. Ze's Extended LSAs carry the U-bit and the scope bits RFC 8362 Section 2 assigns, 0xA021 through 0xA029, with E-AS-External at AS scope (0xC025) and E-Link at link-local scope (0x8028). RFC 8362 Section 2 wants the U-bit set "so that the LSAs will be flooded by OSPFv3 routers that do not understand them", and that is what Ze now sends. Until 2026-09-17 Ze declared those types less 0x8000, so RFC 5340 Section 4.4.1 held every one of them to the link and Ze's Prefix-SIDs stopped at the first router in a mixed area that did not support them.

Ze originates 3 of the 7 Extended LSA types: E-Router, E-Intra-Area-Prefix and E-Inter-Area-Prefix, the three OSPFv3 Segment Routing rides on.

BNG Capabilities

Ze includes a production BNG stack with two access methods: L2TPv2 (RFC 2661) and PPPoE (RFC 2516), both with RADIUS integration (RFC 2865/2866). Most BGP daemons in the comparison table have no BNG functionality at all. L2TP and PPPoE run concurrently on the same daemon and share the same auth, pool, and shaper plugins through a transport-agnostic PPP driver. RADIUS accounting includes real per-subscriber traffic counters read from the kernel PPP interface. Control-plane scale test infrastructure validates 2000 concurrent L2TP sessions across 10 tunnels without requiring root, kernel modules, or Docker.

Where Ze is behind today

The detail tables above are useful. The gaps also need to be visible without reading thirteen tables.

These points are repeated here so visitors do not have to hunt for them.

Positioning

Ze is an open-source network operating system and the successor to ExaBGP. It runs as a daemon on any Linux, or as a gokrazy appliance where gokrazy init starts Ze with no general shell or package manager. It speaks BGP, manages network interfaces, installs routes into the kernel FIB or VPP plane, and serves a config editor over SSH and a web UI. The plugin architecture uses YANG-modelled schemas, so plugins can extend the engine without modifying it.

It is also pre-release, with a first release planned for 2026. It sits beside implementations with years to decades of production hardening; one dates to 1998. Its Go runtime is expected to carry a 10-15% CPU cost compared with the C/Rust implementations in this table, and that estimate has not been benchmarked under real load. BGP confederations, privilege separation, and a custom filter language are still missing, while at least one other implementation has shipped each of them for years. Ze is strongest where it has chosen depth: plugin architecture, YANG-modelled configuration end to end, MCP integration, and a production BNG stack alongside BGP.

ExaBGP is the automation specialist. It pioneered the external-process model where BGP events are delivered as JSON to stdin/stdout of user scripts in any language. Deployed worldwide for traffic engineering, DDoS mitigation, route injection, and SDN integration. It has broad address family support. It is single-threaded Python with no RIB, no best-path selection, and no route reflection by design. ExaBGP is a route injector and event source, not a router.

rustbgpd is an API-first BGP daemon targeting IX route server and SDN controller use cases. It trades address family breadth for modern operational tooling (gRPC, Prometheus, structured logging, TUI, config diagnostics) and memory safety guarantees.

bio-rd is a Go BGP library and daemon originating from DE-CIX. Designed as an embeddable library for building route servers and SDN controllers. It has strong route-server support with RFC 9234 (BGP Roles), BMP, and ECMP. IPv4/IPv6 unicast only: no VPN, EVPN, FlowSpec, or other address families. No Graceful Restart or Route Refresh. Apache-2.0 license.

RustyBGP is an experimental Rust BGP daemon by the GoBGP team (OSRG). It offers a GoBGP-compatible gRPC API and multi-core design with low memory usage. Its own README describes it as having "very basic BGP features": limited address family and policy support. It is useful for research and multi-core experimentation, not yet production-ready.

FRR is the most feature-complete open-source routing suite, covering BGP plus OSPF, IS-IS, PIM, and more. Best choice when you need a full routing stack with broad AFI/SAFI coverage and kernel FIB integration.

BIRD 2/3 dominates IXP route server deployments. It is known for low memory use and a powerful filter language. BIRD 3 (stable Dec 2024) adds multithreading for 5000+ peer scale. Management is CLI/config-file only.

GoBGP pioneered the API-first model with gRPC as its primary interface. Broadest AFI/SAFI coverage. Higher memory and CPU usage than C implementations under large routing workloads. It is best used as an SDN controller or route injector rather than a high-performance router.

OpenBGPd is security-focused with privilege separation and OpenBSD heritage. Deployed at major IXPs. Lean, reliable, and standards-compliant with strong RFC coverage including BGP Roles and Extended Messages. No programmatic API beyond the CLI socket.

freeRtr is a full router OS written entirely in Java. It implements the full routing stack with its own TCP/IP forwarding plane that can be backed by DPDK, XDP, or P4 dataplanes. It has the broadest AFI/SAFI coverage of any implementation in this table, including MUP, MVPN, RTC, and VPN FlowSpec. It has been actively developed since 2012 with 4000+ functional test cases. It has no programmatic API, YANG model, or structured logging.

FAQ

Ze is pre-release. Why trust it yet?

Do not take that on faith: it is backed by 35,000+ unit tests, 2,100+ end-to-end tests, 88 fuzz targets, and interop testing against 9 independent BGP implementations. That evidence can be checked. It is not a promise. Ze does not have operational mileage yet: real deployments over real time, on real networks. Use it in labs first.

Why no BGP confederations yet?

Not implemented yet. It's a real gap against implementations that have had it for years, and it's listed as one plainly above rather than left for you to find in a table.

Why no custom filter language?

Ze does not have a bespoke filter DSL like some implementations here do. Instead, filters are external plugins chained per peer/group: JSON events in, text commands out, over a TLS connect-back socket, in any language that can read lines. You can write a filter in Go, Python, or whatever you already know, instead of learning a new syntax.

Is Ze's performance actually competitive with C/Rust implementations?

Unknown under large route-server load. The current estimate is 10-15% CPU overhead from the Go runtime, but that number has not been benchmarked under real load. Treat it as an open question rather than a claim. See Performance for the actual convergence and throughput numbers measured so far.

Does Ze implement every BGP feature in this table?

No. The BGP-specific gaps are listed above: no BGP confederations, partial BFD integration, no custom filter DSL, no privilege separation, and no embeddable library mode. The full-router comparison belongs on the Open Source Network OS comparison.