-
Notifications
You must be signed in to change notification settings - Fork 2
peers
Pre-Alpha. This page describes behavior that may change.
A BGP peer in Ze is a named entry under bgp { peer <name> { } }. The name is a label you choose, not the peer's IP. You can rename it without losing state, you can refer to it from CLI commands by name, and you can group peers that share defaults under a group { } block.
This page covers what you need to bring up a session, the capabilities and address families you negotiate, prefix limits, authentication, and the per-session policy knobs (route reflection, next-hop control, community filtering, AS override). The configuration model is hierarchical, and most values can live at the global, group, or peer level.
bgp {
router-id 192.0.2.1;
session {
asn { local 65000; }
}
peer upstream {
connection {
remote { ip 10.0.0.1; }
local { ip auto; }
}
session {
asn { remote 65001; }
family {
ipv4/unicast { prefix { maximum 1000000; } }
ipv6/unicast { prefix { maximum 200000; } }
}
}
}
}
That is a complete peer. The router ID and local AS live at the BGP level and are inherited. The peer's transport settings go under connection (remote IP, local bind address). The peer's protocol settings go under session (remote AS, the address families to negotiate, their prefix maximums). Ze will not start without per-family maximums (RFC 4486), and the migration from ExaBGP fills them in with a conservative default that you should adjust before you point it at a full table.
After inheritance has been resolved, every peer must have these set somewhere in its parent chain.
| Field | Where it can live | Notes |
|---|---|---|
connection/remote/ip |
Peer | Peer's IP address. |
session/asn/remote |
Peer | Peer's AS. |
session/asn/local |
BGP, group, or peer | Your AS. |
connection/local/ip |
Suggested | Local bind address. auto lets Ze pick. |
If any required field is missing after inheritance, validators reject the commit with a message naming the field.
The same peer block works for eBGP, iBGP, route reflector clients, and route server clients. The difference is in the values, not in the syntax. eBGP is session/asn/local and session/asn/remote set to different ASNs. iBGP is the same ASN on both sides. A route reflector client adds session/route-reflector-client true; plus the cluster-id configuration described under Session policy.
A peer can be passive (connection/local/connect false), accept-only (connection/remote/accept true), or both. The defaults initiate outbound and accept inbound, which is what you want for a normal eBGP session.
Capabilities live under session/capability/ at any inheritance level. The most common ones:
session {
capability {
asn4; # 4-byte ASN, RFC 6793, on by default
route-refresh; # RFC 2918
extended-message; # RFC 8654, 65535-byte messages
graceful-restart { restart-time 120; }
}
}
role { import provider; } # RFC 9234 BGP Role, at the peer level
asn4 is on by default and you should not turn it off. route-refresh lets you ask the peer to re-send its full table without bouncing the session. graceful-restart is what keeps the RIB across a daemon restart and pairs with the bgp-persist plugin for the disk side. The role container is a peer-level leaf (not inside capability) as role { import <role>; }; values are provider, customer, peer, rs, and rs-client.
These knobs live under session { } and shape how Ze builds outbound UPDATEs and how it treats inbound routes. They are cumulative across BGP, group, and peer levels.
Mark a peer as a route reflector client to have Ze apply RFC 4456 iBGP reflection rules: routes learned from this peer are forwarded to all other peers (clients and non-clients), ORIGINATOR_ID is set if absent, and CLUSTER_LIST is prepended with the local cluster ID.
peer client-a {
connection { remote { ip 10.0.0.1; } }
session {
asn { remote 65000; } # iBGP: same AS as local
route-reflector-client true;
cluster-id 10.0.0.254; # optional, defaults to router-id
}
}
session/cluster-id is kept in sync with the loop-detection filter's cluster-id automatically, so ingress CLUSTER_LIST checks and egress CLUSTER_LIST prepending use the same value even if you only set one.
Controls the NEXT_HOP attribute on outbound UPDATEs.
session {
next-hop auto; # default
# next-hop self; # always rewrite to the local address
# next-hop unchanged; # never rewrite (route-server / third-party NH)
# next-hop 192.0.2.1; # explicit address
}
| Value | Behaviour |
|---|---|
auto |
RFC 4271 default: rewrite for eBGP peers, preserve for iBGP peers. |
self |
Always rewrite to the local address. Common for iBGP overlays. |
unchanged |
Never rewrite. Used by route servers and third-party next-hop setups. |
<ip> |
Set next-hop to the literal address. |
session/as-override rewrites the peer's own ASN in the outbound AS_PATH with the local ASN, so the route is accepted at the far end even though its AS_PATH contains the receiver's ASN. This is the standard trick for VPN or multi-site setups where the same customer ASN appears at several sites.
session { as-override true; }
AS override respects the peer's ASN4 negotiation, so 2-byte and 4-byte sessions both work.
session/asn/local-options tunes how a non-default local ASN shows up in AS_PATH. Both options are leaf-list values; use them individually or together.
session {
asn {
local 65001;
local-options [ no-prepend replace-as ];
}
}
| Option | Behaviour |
|---|---|
no-prepend |
Do not prepend the real local ASN in front of the advertised local-as. |
replace-as |
Replace the real local ASN entirely with the advertised local-as. |
With both set, AS_PATH contains only the advertised local-as and the true ASN is never visible to the peer.
session/community/send controls which community types Ze includes in outbound UPDATEs. Leave it unset to send everything.
session {
community { send [ standard large ]; }
}
| Value | Type |
|---|---|
standard |
RFC 1997 communities (type 8). |
large |
RFC 8092 large communities (type 32). |
extended |
RFC 4360 extended communities (type 16). |
all |
Send all types (default). |
none |
Suppress all community attributes. |
Use none for peers that must never receive your internal tags.
Per-family: inject a synthetic default route towards the peer. Live under session/family/<name>/.
session {
family {
ipv4/unicast {
prefix { maximum 1000000; }
default-originate true;
# default-originate-filter leaf-pass; # optional gate
}
}
}
default-originate is a boolean: true originates 0.0.0.0/0 for IPv4 families, ::/0 for IPv6 families. default-originate-filter is the name of a filter the default must pass before it is emitted. If the filter rejects, the default is not sent. Leave the filter leaf empty to originate unconditionally.
Each family is a child of session/family/ and carries its own prefix limit.
session {
family {
ipv4/unicast { prefix { maximum 1000000; } }
ipv6/unicast { prefix { maximum 200000; } }
ipv4/mpls-vpn { prefix { maximum 500; } }
l2vpn/evpn { prefix { maximum 10000; } }
}
}
IPv4 and IPv6 unicast and multicast are built into the engine. Every other family (FlowSpec, EVPN, VPN, BGP-LS, MPLS labels, MUP, RTC, MVPN, VPLS) is provided by an nlri plugin and only available if the plugin is loaded. Run ze --plugins to see which families are registered.
Prefix limits are mandatory and are enforced per family per peer.
| Setting | Default | Behaviour |
|---|---|---|
maximum |
required | Hard cap. Exceeded means the session is torn down with NOTIFICATION Cease / MaxPrefixes (subcode 1). |
warning |
90 % of maximum
|
Warning threshold. Logged and exported as a metric. |
teardown |
true |
Tear down on exceed. Set false to warn-only and drop further NLRIs in the family. |
idle-timeout |
0 |
Seconds before automatic reconnect after a teardown. 0 means no reconnect. |
ze resolve peeringdb max-prefix <ASN> queries PeeringDB for each peer's ASN and updates the maximums automatically with a configurable margin. Review the change with ze config diff and commit it like any other edit.
Transport-level security lives under connection/.
peer upstream {
connection {
md5 { password "shared-secret"; }
ttl { set 255; max 254; }
}
}
connection/md5/password enables TCP MD5 (RFC 2385). connection/ttl/set and connection/ttl/max together implement RFC 5082 GTSM. TCP-AO is not implemented.
Import and export filter chains live under peer/filter/ and reference filter instances by name. See Route filters for the filter framework.
peer upstream {
filter {
import [ rpki:validate community:scrub ];
export [ aspath:prepend ];
}
}
Filter chains are cumulative from BGP globals to group to peer.
Timers live under timer/ at any inheritance level.
timer {
receive-hold-time 90;
send-hold-time 480;
connect-retry 120;
}
| Leaf | Type | Default | Description |
|---|---|---|---|
receive-hold-time |
uint16 | 90 |
Hold time proposed in OPEN (RFC 4271). 0 or 3–65535. |
send-hold-time |
uint16 | 0 |
Send-side hold timer (RFC 9687). 0 or 480–65535. 0 means auto: max(480, 2 * receive-hold-time). |
connect-retry |
uint16 | 120 |
Connect retry interval in seconds (RFC 4271 Section 8). |
RFC 9687 introduces a send-side hold timer: if Ze cannot write a KEEPALIVE or UPDATE to a peer within send-hold-time seconds, it tears the session down. This protects against a peer that accepts TCP data but never reads from the socket. With the default receive-hold-time of 90, the effective send hold time is 480 seconds.
The behavior { } container holds operational knobs that affect how Ze builds and sends UPDATEs for a peer. It can live at the group or peer level.
behavior {
group-updates true;
manual-eor false;
auto-flush true;
}
| Leaf | Type | Default | Description |
|---|---|---|---|
group-updates |
boolean | true |
Batch NLRI that share the same path attributes into a single UPDATE rather than one UPDATE per prefix. |
manual-eor |
boolean | — | Manual End-of-RIB. When set, Ze does not send EOR automatically after the initial table dump; trigger it from a plugin or the CLI. |
auto-flush |
boolean | — | Auto-flush routes. When set, Ze flushes pending outbound updates to the peer immediately rather than waiting for the reactor loop. |
rib { } controls per-peer Adj-RIB storage and outbound batching.
rib {
adj {
in true;
out true;
}
out {
group-updates true;
auto-commit-delay 0;
max-batch-size 0;
}
}
| Leaf | Type | Default | Description |
|---|---|---|---|
adj/in |
boolean | — | Maintain Adj-RIB-In for this peer. Required for ze show rib routes received. |
adj/out |
boolean | — | Maintain Adj-RIB-Out for this peer. Required for ze show rib routes sent. |
out/group-updates |
boolean | true |
Group outbound updates (same as behavior/group-updates but scoped to the RIB out path). |
out/auto-commit-delay |
uint32 (ms) | 0 |
Delay before auto-committing a batch of outbound updates. 0 means commit immediately. |
out/max-batch-size |
int32 | 0 |
Max updates per outbound batch. 0 means unlimited. |
The process binding connects a peer to a plugin (built-in or external). The content { } sub-container inside process controls the encoding and filtering of events sent to the plugin.
process my-plugin {
receive [ update state ];
send [ update ];
content {
encoding json;
format raw;
attribute minimal;
}
}
| Leaf | Type | Description |
|---|---|---|
encoding |
string | Event encoding format (json, text, …). |
format |
string | Event output format (raw, …). |
attribute |
string | Attribute filter expression controlling which path attributes are included. |
receive lists the event types the plugin wants to consume: update, open, notification, keepalive, refresh, state, sent, negotiated, plus any plugin-registered types. send lists the message types the plugin may inject: update, refresh, enhanced-refresh.
ze# peer list
NAME REMOTE AS STATE
upstream 10.0.0.1 65001 ESTABLISHED
ze# peer upstream show
peer upstream {
connection { remote { ip 10.0.0.1; } }
session { asn { remote 65001; } }
state established
uptime 2h13m
capabilities [ four-octet-asn add-path route-refresh graceful-restart ]
families [ ipv4/unicast ipv6/unicast ]
prefixes received 947213 / max 1000000
}
ze# peer upstream capabilities
ze show peer <name> detail is the long version. ze show bgp summary is the table view across all peers. ze show uptime reports session uptime for every peer in one shot.
- Validation fails with "required field missing": one of
connection/remote/ip,session/asn/remote, orsession/asn/localis not set anywhere in the inheritance chain. - Ze refuses to start with "prefix maximum required": every negotiated address family must have a
prefix { maximum }. Add it undersession/family/<afi-safi>/prefix. - Session bounces immediately after Established: check
peer <name> showfor capability mismatches and the log for the peer's NOTIFICATION code. - Session never makes it past Active: TCP is not getting through. Check
connection/md5/password, the source IP thatconnection/local/ipresolves to, and anyconnection/ttlor firewall rules in the path.
- Route filters for import/export filter chains.
- Policies for what the policy surface covers.
- Route reflection for the route server model and iBGP RR context.
- Configuration overview for the YANG model and the commit workflow.
- Quick start for the shortest path to a session.
- ExaBGP migration if you are converting an existing config.
Adapted from main/docs/guide/configuration.md, the
ze-bgp-conf.yangschema, and main/docs/features/bgp-protocol.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