Ze commands fall into two categories: shell commands that run locally and runtime commands sent to the running daemon via SSH.
For the forward-looking cross-vendor roadmap (which commands VyOS /
Junos / Nokia / Arista expose and ze's status per row), see
command-catalogue.md.
Run directly from the terminal. No daemon required (except ze signal, ze status,
ze cli, and daemon-targeted ze show subcommands).
Some ze show subcommands run locally: version, bgp decode, bgp encode,
env, schema, yang, completion.
Start the daemon or access subcommands.
ze <config-file> # Start daemon with config
ze start # Start daemon from database
| Flag | Purpose |
|---|---|
-d, --debug |
Enable debug logging |
-f <file> |
Use filesystem directly, bypass blob store |
--plugin <name> |
Load plugin before starting a YANG/native config (repeatable). Hub/orchestrator configs reject this; use plugin { external ... } in the config instead. |
--plugins |
List available internal plugins |
--pprof <addr:port> |
Start pprof HTTP server |
-V, --version |
Show version (also available as ze show version) |
--chaos-seed <N> |
Enable chaos self-test mode |
--chaos-rate <0-1> |
Fault probability per operation |
--server <host:port> |
Override hub address for managed mode |
--name <name> |
Override client name for managed mode |
--token <token> |
Override auth token for managed mode |
--color |
Force colored output (even when not a TTY) |
--no-color |
Disable colored output (also: NO_COLOR env var, TERM=dumb) |
Validate a configuration file without starting the daemon.
ze config validate <config-file>
ze config validate -q <config-file> # Quiet: exit code only
ze config validate --json <config-file> # JSON output
| Flag | Purpose |
|---|---|
-v |
Verbose output |
-q |
Quiet mode (exit code only) |
--json |
JSON output |
Exit codes: 0 = valid, 1 = invalid, 2 = file not found.
Validation includes the commit-time backend capability gate: a config whose
active backend leaf does not implement a feature it uses (e.g. backend vpp
with a bridge, tunnel, wireguard, veth, or mirror entry) is
rejected with one error per offending YANG path, matching the diagnostic
the running daemon produces on reload. See
Backend Capability Errors.
Configuration management.
Editing:
ze config edit [file] # Interactive editor
ze config set <file> <path> <value>
ze config deactivate <file> <path> # Mark a node inactive (kept in file, skipped at apply)
ze config activate <file> <path> # Clear the inactive flag on a node
deactivate and activate accept any node type: leaf, container, list entry,
or leaf-list value. The deactivated node round-trips through save/load and is
skipped at apply time. See docs/guide/config-deactivate.md.
Storage:
ze config import <file>... # Import files into the database
ze config import --name <n> <file> # Import under a different name
ze config rename <old> <new> # Rename a config in the database
ze config ls [prefix] # List files in database
ze config cat <key> # Print database entry
Inspection:
ze config validate <file> # Validate configuration file
ze config dump <file> # Dump parsed configuration
ze config diff <f1> <f2> # Compare two configs
ze config diff <N> <file> # Compare with rollback revision
ze config fmt <file> # Format and normalize
History:
ze config history <file> # List rollback revisions
ze config rollback <N> <file> # Restore revision N
ze config archive <name> <file> # Archive config (see config-archive.md)
Migration:
ze config migrate <file> # Convert old format to current
| Flag | Purpose |
|---|---|
-f |
Bypass database, use filesystem directly |
-o <output> |
Output file (migrate) |
--dry-run |
Show what would be migrated without changes (migrate) |
--list |
List available transformations (migrate) |
--format <fmt> |
Output format: set (default) or hierarchical (migrate) |
Send commands to the running daemon via SSH.
ze signal reload # Reload configuration
ze signal stop # Graceful shutdown (no GR marker)
ze signal restart # Graceful restart (with GR marker)
ze signal reboot # Graceful shutdown + OS reboot (with GR marker, requires root on Linux)
ze signal status # Dump daemon status
ze signal quit # Immediate exit + goroutine dump
| Flag | Purpose |
|---|---|
--host |
SSH host (default: 127.0.0.1 or ze_ssh_host) |
--port |
SSH port (default: 2222 or ze_ssh_port) |
Exit codes: 0 = ok, 1 = not running, 4 = command failed. Reload is transactional: the daemon stages the new config as a candidate version, runs verification and apply, then promotes the candidate to active only after the runtime accepts it.
Check if the daemon is running.
ze status
| Flag | Purpose |
|---|---|
--host |
SSH host |
--port |
SSH port |
Exit codes: 0 = running, 1 = not running.
BGP protocol tools (offline, no daemon needed).
ze bgp decode <hex> # Decode BGP message hex to JSON
ze bgp encode <route-command> # Encode route command to BGP hex
ze bgp plugin cli # Plugin debug shell (5-stage handshake + interactive)
ze bgp plugin cli --name <name> # Debug shell with custom plugin name
# Also available via YANG verb dispatch (same behavior, no daemon needed):
ze show bgp decode <hex>
ze show bgp encode <route-command>
decode flags:
| Flag | Purpose |
|---|---|
--open |
Decode as OPEN message |
--update |
Decode as UPDATE message |
--nlri <family> |
Decode as NLRI for family |
-f <family> |
Address family |
--json |
JSON output |
--plugin <name> |
Load plugin (repeatable) |
encode flags:
| Flag | Purpose |
|---|---|
-f <family> |
Address family (default: ipv4/unicast) |
-a <asn> |
Local ASN (default: 65533) |
-z <asn> |
Peer ASN (default: 65533) |
-i |
Enable feature |
-n |
Dry run |
--no-header |
Exclude BGP header |
--asn4 |
4-byte ASN (default: true) |
Operational report bus. A single place for Ze subsystems to surface operator-visible issues. Warnings are state-based (a condition is currently problematic and may resolve). Errors are event-based (something already happened; no clear API). Both commands query the same in-process report bus and return newest-first JSON snapshots.
ze show warnings # JSON: {"warnings": [...], "count": N}
ze show warnings source bgp # only warnings from the bgp subsystem
ze show errors # JSON: {"errors": [...], "count": N}
ze show errors source l2tp # only errors from the l2tp subsystem
ze show errors source l2tp count 5 # last 5 errors from l2tp
Issue shape (every entry in both responses):
| Field | Type | Description |
|---|---|---|
source |
string | Subsystem that raised the issue (bgp, config, iface, ...) |
code |
string | Stable kebab-case identifier of the condition or event |
severity |
string | warning or error |
subject |
string | What the issue is about: peer address, transaction id, file path |
message |
string | Human-readable one-liner |
detail |
object | Optional structured context (family, code/subcode, reason, ...) |
raised |
RFC 3339 time | When the issue first appeared on the bus |
updated |
RFC 3339 time | Most recent raise time (warnings advance; errors equal raised) |
Day-one BGP vocabulary (raised by the BGP reactor):
| Severity | Source/Code | When raised | When cleared |
|---|---|---|---|
| warning | bgp / prefix-threshold |
Per-family prefix count crosses the configured warning threshold upward | Per-family count drops below threshold |
| warning | bgp / prefix-stale |
peer { prefix { updated ... } } date is older than 180 days |
Peer re-added with a fresher date, or peer removed |
| error | bgp / notification-sent |
This ze instance sends a NOTIFICATION to a peer (code/subcode in detail) |
Never (errors are events) |
| error | bgp / notification-received |
A peer sends a NOTIFICATION to this ze instance | Never |
| error | bgp / session-dropped |
An Established session ends without a NOTIFICATION exchange (TCP loss, hold-timer with no notification, peer FIN) | Never |
Capacity limits (configurable via env vars):
| Env var | Default | Maximum | Purpose |
|---|---|---|---|
ze.report.warnings.max |
1024 | 10000 | Cap on active warning set, oldest-by-Updated evicted at cap |
ze.report.errors.max |
256 | 10000 | Ring buffer size for recent error events |
Over-limit raise calls are silently rejected and logged at debug level. Field length limits (Source 64, Code 64, Subject 256, Message 1024, Detail 16 keys) prevent any producer from pushing multi-megabyte entries.
Login banner integration: the Ze CLI login banner reads from the same bus,
filtered by source bgp. One active warning shows the detail line; multiple
warnings collapse to a count line pointing at show warnings.
Audit and accounting visibility for operator actions.
ze show audit
ze show audit action config-commit
ze show audit actor alice surface web count 20
ze show audit since 2026-05-24T10:00:00Z until 2026-05-24T11:00:00Z
ze show aaa accounting
show audit returns entries and count. Each entry includes timestamp,
actor, remote-addr, surface, action, detail, and outcome.
Filters are optional and can be combined. Time filters use RFC 3339.
show aaa accounting currently reports TACACS+ accounting queue drops:
dropped-records is the number of START/STOP accounting records that could not
be queued because the worker was stopped or the queue was full.
Daemon process introspection. Three sibling commands surface the Go runtime state for the running ze process. Available via daemon SSH (online RPC); YANG registration only.
ze show system memory # runtime.MemStats (alloc, heap, GC) + hardware enrichment
ze show system cpu # goroutine count, logical CPUs, GOMAXPROCS + hardware
ze show system date # wall-clock time: RFC3339, Unix, timezone
ze show system platform # runtime platform type and capabilities
Each response is a flat JSON map with kebab-case keys:
| Command | Top-level keys |
|---|---|
show system memory |
alloc, total-alloc, sys, heap-alloc, heap-sys, heap-in-use, heap-objects, stack-in-use, num-gc, gc-cpu-pct, hardware (optional: physical memory + ECC from host.DetectMemory()) |
show system cpu |
num-cpu, num-goroutines, max-procs, go-version, hardware (optional: host.DetectCPU()) |
show system date |
time (RFC3339), unix, unix-nano, timezone, utc-offset-secs |
show system platform |
type (gokrazy, systemd, container, plain-linux, darwin), read-only-root, perm-available, systemd-available, gokrazy-update-socket, gokrazy-ui-available, reboot-allowed, persistent-storage-writable, fd-limit-soft-current, fd-limit-hard-max, fd-limit-raisable |
show system conntrack |
count, max, buckets, expect-max, accounting, timestamp, checksum, log-invalid, modules (loaded nf_conntrack_* list), timeouts (per-protocol), tcp-behavior (be-liberal, loose, max-retrans, ignore-invalid-rst) |
The hardware subobject under memory and cpu mirrors the data
returned by show host memory / show host cpu. Both paths are
correct; pick show system * when you want runtime-first with hardware
as context, show host * when you want hardware-first.
Host hardware inventory. Read-only, no daemon required. Walks sysfs/procfs
(and issues best-effort ethtool ioctls for NIC firmware/rings) to produce
a structured JSON description of the machine. Defaults to JSON output for
pipeline consumption (jq, Prometheus scrapers, SNMP shims); use
--text for human-readable summaries.
ze host show # Full inventory (all sections), JSON
ze host show cpu # CPU only
ze host show nic # Physical NICs (virtual interfaces filtered)
ze host show dmi # DMI/SMBIOS board identity
ze host show memory # /proc/meminfo + ECC counters (edac)
ze host show thermal # hwmon sensors + per-CPU throttle counts
ze host show storage # Block devices + NVMe firmware
ze host show kernel # Kernel release, cmdline, microcode, arch flags
ze host show all # Every section in one payload
ze host show --text cpu # Human-readable summary
The same sections are also available as RPCs over ze cli to a running
daemon: show host cpu, show host nic, etc. Online and offline paths
share the same detection library; the JSON shapes are identical.
Sections:
| Section | Fields (kebab-case keys) |
|---|---|
cpu |
vendor, model-name, family, model, stepping, logical-cpus, physical-cores, threads-per-core, hybrid, scaling-driver, hwp-available, base-freq-mhz, max-freq-mhz, microcode, cores[] with per-core role (performance/efficient/uniform), current-freq-mhz, core-throttle-count, package-throttle-count |
nic |
Per physical interface: name, driver, pci-vendor, pci-device, mac, link-speed-mbps, duplex, carrier, rx-queues, tx-queues, ring-rx, ring-tx, firmware-version |
dmi |
system-vendor, system-product, board-*, bios-*, chassis-* |
memory |
total-bytes, free-bytes, available-bytes, buffers-bytes, cached-bytes, swap-total-bytes, swap-free-bytes, ecc-correctable-errors, ecc-uncorrectable-errors, ecc-present |
thermal |
sensors[] (hwmon: name, device, temp-mc, alarm), throttle[] (per-CPU core-throttle-count, package-throttle-count) |
storage |
devices[] with name, size-bytes, model, serial, transport (nvme/sata/mmc/virtio/unknown), rotational, nvme-firmware-version (NVMe only), smart (via direct ioctl, no smartctl binary: healthy, temp-celsius, power-on-hours, error-count, percent-used (NVMe), available-spare (NVMe); unavailable + unavailable-note when device lacks SMART or insufficient privileges) |
kernel |
release, version, architecture, cmdline, boot-time (RFC3339), boot-time-unix, microcode-revision, arch-flags[] (security-relevant subset: smep, smap, ibt, user_shstk, ibrs, ibrs_enhanced, ssbd) |
All temperatures are reported in millicelsius (kernel hwmon convention).
All sizes in bytes. All frequencies in MHz. Unreadable sysfs files
are omitted from the JSON rather than returning null or an empty string.
Permission errors are recorded in the inventory's errors[] array.
Virtual interface filtering: ze host show nic only reports physical
interfaces. The filter is structural (presence of
/sys/class/net/<n>/device/) rather than a driver-name allowlist, so
new virtual drivers (wireguard, ipvlan, etc.) are filtered uniformly.
Platform: Linux only. Darwin and other platforms return
ErrUnsupported per section; ze host show reports "unsupported on this
platform" with exit 0 so scripts can probe gracefully.
Online RPC (requires running daemon with storage { smart { enabled true } } config):
show storage smart # Per-device SMART health status
Returns a JSON array of per-device objects:
| Field | Description |
|---|---|
name |
Block device name (e.g. sda, nvme0n1) |
transport |
nvme, sata, or unknown |
healthy |
SMART overall health assessment |
temp-celsius |
Current temperature (0 = not reported) |
power-on-hours |
Cumulative powered-on hours |
error-count |
Reallocated sector count (ATA) or media errors (NVMe) |
percent-used |
NVMe endurance estimate (0-255, NVMe only) |
available-spare |
NVMe spare capacity percentage (NVMe only) |
smart-enabled |
Whether SMART enable command succeeded |
last-checked |
Timestamp of last health poll |
last-short-test |
Timestamp of last short self-test (if scheduled) |
last-long-test |
Timestamp of last extended self-test (if scheduled) |
Temperature alerts are emitted to the report bus (show warnings / show errors):
temp-high (informational threshold), temp-rising (rate-of-change), temp-critical (critical threshold), smart-failing (health status failed).
Generate a tech-support archive for troubleshooting. Collects system state, health checks, configuration, logs, and diagnostics into a compressed tar.gz with one JSON file per module. No shell-outs; gokrazy-safe.
ze support # Full bundle, all 19 modules
ze support --module version,doctor # Only named modules
ze support --exclude logs # All except named modules
ze support --json # Output manifest JSON to stdout
ze support --list-modules # List available modules
ze support --reason "BGP flap" # Embed reason in manifest
ze support --sensitive # Include passwords (default: redacted)
ze support --since 2h # Time scope for log collection
ze support --output /var/support/ # Output directory (default: cwd)
OS network interface management (standalone, no daemon needed for most commands).
Show uses the verb syntax: ze show interface.
ze show interface # List all interfaces (also via daemon SSH)
ze show interface brief # One-line-per-interface summary
ze show interface detail <name> # Show details for one interface
ze show interface counters <name> # Counters only for named interface
ze show interface type <type> # Filter by type (ethernet, bridge, vxlan, wireguard, ...)
ze show interface errors # Interfaces with non-zero Rx/Tx error or drop counters
ze show interface rate # Per-second rate data for all interfaces
ze show interface rate <name> # Per-second rate data for one interface
ze show interface --json # JSON output
ze interface create dummy <name> # Create a dummy interface
ze interface create veth <n> <p> # Create a veth pair
ze interface delete <name> # Delete an interface
ze interface unit add <name> <id> [vlan-id <vid>] # Add a logical unit
ze interface unit del <name> <id> # Delete a logical unit
ze interface addr add <name> unit <id> <cidr> # Add IP address
ze interface addr del <name> unit <id> <cidr> # Remove IP address
ze interface migrate ... # Make-before-break migration (requires daemon)
show interface type <type> is case-insensitive; unknown types reject
with the sorted list of types actually present on the system. Empty-Type
interfaces are hidden from both the response and the valid-types list.
show interface errors skips interfaces without stats and interfaces
whose RxErrors, RxDropped, TxErrors, TxDropped counters are all
zero. The response includes only the four counter fields per interface
for compact diffing across snapshots.
Traffic control (TC) state. Queries the active TC backend for qdisc, class, and filter state per interface. Returns "traffic control not available on this platform" when no TC backend is loaded (e.g. on macOS).
ze show traffic # Summary of all interfaces with qdiscs
ze show traffic <ifname> # Detail for one interface
Per-collector flow export statistics for the flowexport component (sFlow v5,
NetFlow v9, IPFIX). Returns {"status": "not-configured"} when no
flow-export { } section is present.
ze show flow-export # All configured collectors
ze show flow-export <collector> # One collector by name (error if not found)
Each entry reports name, address, port, protocol, datagrams-sent,
bytes-sent, errors, sequence, and last-export-time (Unix seconds,
omitted before the first poll). JSON by default; full pipe operators supported.
See the Flow Export guide.
Kernel routing and neighbor tables. Both commands dispatch through the iface backend; on the netlink backend they read the live kernel state, on VPP they reject under exact-or-reject since the kernel FIB/ARP table is not the authoritative forwarding source there.
ze show ip arp # Kernel neighbor table (IPv4 ARP + IPv6 ND)
ze show ip arp --family ipv4 # IPv4 only
ze show ip arp --family ipv6 # IPv6 only
ze show ip route # Full kernel routing table (all protocols)
ze show ip route <cidr> # Filter to an exact CIDR match
ze show ip route default # Default route(s) (0.0.0.0/0, ::/0)
show ip arp returns per-entry address, mac-address, device,
family, and state (reachable, stale, delay, probe, failed,
permanent, noarp, incomplete). Unresolved entries (no IP) are skipped.
FAILED and INCOMPLETE entries are kept with an empty MAC so operators
can diagnose neighbor discovery problems.
show ip route renders the protocol field by name for well-known
values (kernel, static, bgp, ra, dhcp, zebra, ze for RTPROT_ZE=250, plus
ospf/isis/rip/eigrp/babel) and as a decimal string otherwise. Connected
routes have an empty nexthop; the source field carries the
preferred-source IP when the kernel reports one.
MPLS label-switching forwarding table, read directly from the kernel
AF_MPLS routing table (the authoritative dataplane state, like show ip route for IP).
ze show mpls forwarding # All installed MPLS forwarding entries
ze show mpls forwarding --limit 500 # Cap the response size
Each entry reports the incoming label (in-label), the operation
applied (swap when an outgoing label stack is programmed, pop for
disposition / implicit-null), any out-labels, the next-hop, and the
egress device. On non-Linux platforms the table is empty (the kernel
MPLS FIB is Linux-only).
PKI certificate store introspection. Shows certificates loaded from
the pki {} config section.
ze show pki certificates # List all loaded certs (CA + device)
ze show pki certificate <name> # Full details for a named certificate
ze show pki certificate <name> pem # PEM-encoded certificate (+ intermediate)
ze show pki certificate <name> bundle pem # Certificate + private key in one PEM
ze show pki certificate <name> fingerprint # SHA-256 fingerprint (colon-separated hex)
ze show pki certificate <name> fingerprint sha512 # SHA-512 fingerprint
show pki certificates returns a sorted list of all loaded
certificates with name, type (ca/device), subject CN, issuer CN,
expiry date, key algorithm, and validity status.
show pki certificate <name> returns full details: subject,
issuer, serial, validity period, key algorithm, key size, SANs,
key usage, private key presence, and chain validation status.
show pki certificate <name> pem returns the certificate in PEM
format. Includes the intermediate certificate if one is stored.
show pki certificate <name> bundle pem returns the certificate
and its private key concatenated in PEM format (device certificates
only). Useful for clients that need a single PEM file (e.g. OpenConnect).
show pki certificate <name> fingerprint [sha256|sha384|sha512]
returns the DER fingerprint as colon-separated hex. Defaults to SHA-256.
Firewall (nftables) introspection. Requires the firewall { ... }
section in config so the firewall plugin loads and applies a backend;
without it the handlers reject under exact-or-reject.
ze show firewall ruleset <name> # Rules + per-term counters for table <name>
ze show firewall group # List all known group names (applied sets)
ze show firewall group <name> # Elements of a named group
show firewall ruleset joins the applied desired state (chains +
terms) with kernel counters read back via the nft backend's GetCounters
call. Every rule is auto-instrumented with an anonymous counter
expression when applied; the term name is stored in nftables'
Rule.UserData and recovered on readback so the join is explicit (not
index-based). Rejects when no firewall backend is loaded or when the
active backend is not nft.
show firewall group reads from the applied-state snapshot, not
the kernel -- groups (nftables named sets) are part of the desired
state the operator typed into config. Calling with no argument returns
{ name, tables[], members } per group; a positional name returns the
raw elements.
ze show system uptime # Daemon start time and uptime duration
Returns start-time (RFC3339) and uptime (truncated to seconds).
Returns an error when the daemon is not running (context is nil or the
reactor is absent).
ze show system sockets # All TCP and UDP sockets
ze show system sockets tcp # TCP only
ze show system sockets tcp state ESTABLISHED # Filter by state
ze show system sockets tcp port 179 # Filter by port
Returns JSON array of sockets with protocol, local-addr, local-port, remote-addr, remote-port, state, tx-queue, rx-queue. Linux only.
ze show system kernel-log # Last 50 entries
ze show system kernel-log count 20 # Last 20 entries
ze show system kernel-log level err # Errors and above
ze show system kernel-log level err count 10 # Combined
Reads /dev/kmsg. Returns entries with level, sequence, timestamp-us, message. Levels: emerg, alert, crit, err, warning, notice, info, debug. Linux only.
ze show system goroutines summary # Count by state
ze show system goroutines blocked # Only waiting goroutines
ze show system goroutines full # Full stack dump
The full mode uses singleflight deduplication: concurrent requests share
a single 16 MB allocation.
ze show tcp-check <host> <port> # Basic connectivity test
ze show tcp-check <host> <port> timeout 3s # Custom timeout (1s-30s)
ze show tcp-check <host> <port> source 10.0.0.1 # Bind source IP
Returns result (connected/refused/timeout) and latency-ms.
ze show traceroute 8.8.8.8 # Trace path to target
ze show traceroute 8.8.8.8 max-hops 10 # Limit to 10 hops (1-64)
ze show traceroute 8.8.8.8 timeout 2s # Per-probe timeout (1s-30s)
ze show traceroute 8.8.8.8 probes 1 # 1 probe per hop (1-10)
ze show traceroute 2001:db8::1 # IPv6 target
ze show traceroute example.com # Hostname (resolved to IP)
Returns JSON with target and per-hop array. Each hop has: hop (int), addr (string or "*" for timeout), rtt-ms (float or null), ttl (int). Requires CAP_NET_RAW (root privilege enforced at startup).
monitor traceroute 8.8.8.8 # Live mtr-style path trace (alt screen)
monitor traceroute 8.8.8.8 max-hops 10 # Limit to 10 hops (1-64, default 16)
monitor traceroute 8.8.8.8 | log # Appending scrollback, one line per round
monitor traceroute 8.8.8.8 | log | resolve # Log with reverse DNS in hop legend
monitor traceroute 8.8.8.8 | log | origin # Log with ASN/network in hop legend
monitor traceroute 8.8.8.8 | table # Alt screen with formatted output
monitor traceroute 8.8.8.8 | json # Alt screen with JSON per round
Continuous mtr-style traceroute. Plain mode uses the alt screen with columns: Hop, Address, Loss%, Snt, Last, Avg, Best, Wrst, StDev. Each round is a complete trace. Esc/q/Ctrl-C to stop; last snapshot copied to scrollback.
In | log mode, the hop legend (printed every 25 rounds) is enriched by
| resolve (adds reverse DNS hostnames) or | origin (adds ASN name
or AS number from Team Cymru).
Requires CAP_NET_RAW.
monitor ping 8.8.8.8 # Live ping (alt screen, 1s interval)
monitor ping 8.8.8.8 interval 500ms # Custom interval (100ms-30s)
monitor ping 8.8.8.8 timeout 3s # Custom timeout (1s-30s)
monitor ping 8.8.8.8 | log # Appending scrollback, one line per reply
monitor ping 8.8.8.8 | table # Alt screen with formatted stats
monitor ping 8.8.8.8 | json # Alt screen with JSON per reply
Continuous ICMP ping. Plain mode uses the alt screen showing: Sent, Recv, Loss%, Last, Min, Avg, Max, StDev. Esc/q/Ctrl-C to stop.
Default interval: 1s. Default timeout: 5s.
Requires CAP_NET_RAW.
ze show capture interface eth0 # Capture 100 packets, pcap output
ze show capture interface eth0 count 10 # Capture 10 packets
ze show capture interface eth0 duration 5s # Capture for 5 seconds
ze show capture interface eth0 tcp port 179 count 10 # BPF filter: TCP port 179
ze show capture interface eth0 format text # Human-readable one-line-per-packet
ze show capture interface eth0 snap-len 128 format text # Truncate packets to 128 bytes
ze show capture interface eth0 udp port 53 count 5 format text # DNS traffic, text output
Live packet capture using AF_PACKET raw sockets with BPF filters. Replaces
tcpdump on gokrazy appliances. Default output is base64-encoded pcap (pipe to
base64 -d > capture.pcap for Wireshark). format text produces one line per
packet: TIMESTAMP PROTO SRC:PORT -> DST:PORT FLAGS LEN HEX. Limits: count
1-10000, duration 1s-60s, snap-len 64-65535. One active capture per interface.
Linux only (requires CAP_NET_RAW). Pure Go, no libpcap/cgo dependency.
ze show system file-descriptors summary # Counts by type + limits
ze show system file-descriptors detail # Full FD list with targets
Returns total, by-type (socket/pipe/file/anon_inode), soft-limit, hard-limit. Linux only.
ze show dns lookup example.com # A record (default)
ze show dns lookup example.com type AAAA # AAAA record
ze show dns lookup example.com type MX # MX record
Returns structured JSON with name, type, records, count, query-time-ms. Supported types: A, AAAA, MX, NS, TXT, CNAME, PTR.
ze show dns cache stats # Cache hit/miss/eviction counters + hit-rate/miss-rate
ze show dns cache list # List all non-expired cached entries (sorted by TTL ascending)
ze show dns cache record example.com # Show cached entries for a specific name
stats returns entries, capacity, hits, misses, evictions, expired, hit-rate, miss-rate.
list returns each entry with name, type, records, and ttl-seconds.
record <name> filters cached entries by name (all types for that name).
clear dns cache # Flush all entries and reset all counters
clear dns cache stats # Zero counters without removing entries
clear dns cache record example.com # Delete all entries matching name (all types)
clear dns cache record example.com type AAAA # Delete a single entry by name and type
ze show system profile heap # Heap profile
ze show system profile cpu duration 10s # CPU profile (1s-60s)
ze show system profile goroutine # Goroutine profile
ze show system profile allocs # Allocation profile
Returns base64-encoded pprof data. CPU profiling is mutex-protected: concurrent requests return an error.
ze show system memory-map # Process memory from /proc/self/status
Returns vm-rss-kb, vm-size-kb, vm-swap-kb, vm-peak-kb, vm-data-kb, vm-stack-kb, threads. Linux only.
ze show system update # Firmware update status
ze show system update | json # Machine-readable output
Returns: running-version, remote-version, update-available, status, last-check, last-error, download-status, download-sha256, staged-version, staged-path, restart, server-paused.
Status values: "up to date", "update available", "downloading", "verifying", "staged", "paused by server", "waiting for maintenance window", "waiting for spread", "check failed", "not configured", "error: ...".
ze show system update history # Last 20 update events
ze show system update history | table # Tabular view
Returns an array of events with: timestamp, from (version), to (version), result. Result values: "success", "failed-download", "failed-checksum", "failed-stage", "blocked-minimum-version", "paused".
History is persisted to ze-update-history.json in the binary's directory and
survives restarts.
ze update system firmware check # Immediate version check (bypass interval timer)
ze update system firmware download # Download now (bypass spread, maintenance window)
ze update system firmware apply # Full cycle: download+verify+stage+restart
ze update system firmware restart # Restart into staged version now
ze update system firmware rollback # Restore .prev binary and restart
All firmware commands are RPC-only (no config state change). They override the automated schedule for one-shot operation.
apply and download bypass server-side pause (pause is for automated fleet
rollout, not manual intervention). Both check minimum-version and warn when
sha256 is absent from the manifest.
rollback renames the .prev backup to the target binary and restarts. After
rollback, .prev no longer exists and the new version is gone from disk.
ze show summary # Every configured peer
ze show summary ipv4 # Expanded to ipv4/unicast
ze show summary ipv6 # Expanded to ipv6/unicast
ze show summary l2vpn # Expanded to l2vpn/evpn
ze show summary <afi>/<safi> # Full AFI/SAFI form (e.g. ipv4/vpn)
The family argument is validated against the families any peer has actually negotiated; unknown or un-negotiated families reject with the sorted set of currently-negotiated families so the operator sees exactly what is reachable on the running daemon.
ze ping <target> [--count N] [--interface IF]
ze traceroute <target> [--probes N] [--interface IF]
Thin wrappers over the OS's ping and traceroute binaries.
Online (daemon running):
show crashes # List crash files with timestamp and size
show crashes latest # Display full content of most recent crash report
Offline (no daemon required):
ze crashes show # List crash files (JSON)
ze crashes show latest # Display most recent crash report
Crash reports contain the panic stack trace, ring buffer context (last 64
log entries before the crash), version, build date, and uptime. Crash files
are stored in the autodetected crash directory (see ze.crash.dir env var).
The offline variant works when the daemon is down (which is when you need it most, after a crash).
ze clear interface counters # Reset counters on every managed interface
ze clear interface counters <name> # Reset counters on one interface
Grammar uses action-before-identifier: counters keyword first, then the
optional interface name. Bare ze clear interface counters (no name) clears
all interfaces. The old forms clear interface <name> counters and
clear interface <name> are still accepted with a deprecation warning.
Errors in argument shape (unknown trailing keyword, three or more tokens)
reject with the usage line rather than silently defaulting to "all".
The clear verb resets runtime/operational state without touching
configuration. Backends that expose a real counter-reset syscall
(VPP's sw_interface_clear_stats, once wired) zero the kernel
counters directly. Linux netlink has no generic counter-reset, so ze
falls back to a per-interface baseline: the current raw counter
values are captured, and every subsequent show interface [counters]
read subtracts the baseline before returning so the operator sees
"since last clear" deltas.
Wrap detection: if a subsequent read observes a raw counter lower than its baseline (interface bounce, driver reload, delete+recreate), ze treats it as a kernel-level reset, drops the baseline, and returns the raw value. Subsequent reads resume from the kernel's new zero without underflow.
migrate flags (dispatched to running daemon via SSH):
| Flag | Purpose |
|---|---|
--from <iface>.<unit> |
Source interface and unit (required) |
--to <iface>.<unit> |
Destination interface and unit (required) |
--address <cidr> |
IP address to migrate (required) |
--create <type> |
Create new interface: dummy, veth, bridge |
--timeout <duration> |
BGP readiness timeout (default: 30s) |
ExaBGP compatibility tools.
ze exabgp plugin <cmd> [args] # Run ExaBGP plugin with ze
ze exabgp migrate <file> # Convert ExaBGP config to ze
ze exabgp migrate --env <file> # Convert ExaBGP env file to ze config
migrate flags:
| Flag | Purpose |
|---|---|
--dry-run |
Show what would be done without output |
--env <file> |
Migrate ExaBGP INI environment file |
plugin flags:
| Flag | Purpose |
|---|---|
--family <family> |
Address family (repeatable) |
--route-refresh |
Enable route-refresh |
--add-path <mode> |
ADD-PATH mode: receive, send, both |
When launched by ze's process manager (as an external plugin), the bridge detects
ZE_PLUGIN_HUB_TOKEN and automatically uses TLS connect-back with the SDK.
In standalone mode (no env var), it uses stdin/stdout with inline MuxConn framing.
Schema discovery.
ze schema list # List registered schemas
ze schema show <module> # Show YANG module content
ze schema handlers # List handler-to-module mapping
ze schema methods [module] # List RPCs from YANG
ze schema events [module] # List notifications
ze schema protocol # Show protocol version
All subcommands accept --json.
YANG analysis.
ze yang completion # Detect prefix collisions
ze yang tree # Print unified tree
ze yang doc [command] # Command documentation
| Flag | Purpose |
|---|---|
--json |
JSON output |
--commands |
Show command tree (tree) |
--config |
Show config tree (tree) |
--min-prefix <N> |
Minimum prefix length (completion, default: 1) |
--list |
List commands (doc) |
Bootstrap the database (interactive or piped).
ze init # Interactive setup
ze init -managed # Fleet mode
ze init -force # Replace existing database
Prompts for: username, password, host (127.0.0.1), port (2222), name (hostname).
After credentials are stored, ze init discovers OS network interfaces via netlink
and writes initial interface configuration (ethernet, bridge, veth, dummy, loopback)
to the database as ze.conf.
Zero-touch provisioning server. Generates a ze config from CLI flags and
forks ze - to start DHCP+PXE, TFTP, and HTTP servers for PXE-booting
target machines with a gokrazy image.
ze install remote --interface eth0 --network 10.0.0.0/24 \
--image /path/to/gokrazy.img \
--ssh-username admin --ssh-password secret
| Flag | Purpose |
|---|---|
--interface |
Network interface for provisioning (required) |
--network |
Provisioning network CIDR, /8../30 (required) |
--image |
Path to gokrazy disk image (required) |
--ssh-username |
Admin username for installed target (required) |
--ssh-password |
Admin password, bcrypt-hashed before use (required) |
--address |
Override server IP (default: first IPv4 on interface) |
The DHCP pool range scales with subnet size: for a /24 the pool spans the full host range minus the server IP; for a /28 only the available hosts are offered. PXE options select BIOS or UEFI bootfile based on client architecture (option 93).
Requires root on Linux (DHCP port 67, TFTP port 69, HTTP port 80). On gokrazy appliances ze runs as root by default.
SIGTERM/SIGINT are forwarded to the child ze process for clean shutdown.
Manage ze as a systemd service on standard Linux hosts. This command is for non-gokrazy deployments where ze runs under systemd.
sudo ze service install # write and enable ze.service
sudo ze service install --start # install, enable, and start
ze service install --dry-run # print the unit file, no writes
ze service status # run systemctl status ze.service
sudo ze service uninstall # stop, disable, and remove the unit
| Flag | Purpose |
|---|---|
--config <dir> |
Override the config directory used in the unit file |
--start |
Start the service after enabling it |
--force |
Overwrite an existing /etc/systemd/system/ze.service |
--dry-run |
Print the generated unit file to stdout without root, systemctl, or filesystem writes |
ze service install requires Linux, systemctl, root, and an existing
<config-dir>/database.zefs. Run sudo ze init first. The generated unit runs
as user/group ze, sets XDG_RUNTIME_DIR=/run/ze, creates /run/ze through
RuntimeDirectory=ze, and grants CAP_NET_ADMIN, CAP_NET_RAW, and
CAP_NET_BIND_SERVICE through systemd capabilities.
The daemon socket is /run/ze/ze.socket under this unit. Configure
daemon { socket "/run/ze/ze.socket"; } or run operator commands with
XDG_RUNTIME_DIR=/run/ze so local CLI commands connect to the same socket.
Bcrypt-hash a plaintext password for use in system.authentication.user.password.
Reads from stdin (piped, single line) or interactive TTY (prompts twice for
confirmation). Uses bcrypt.DefaultCost (10), the same cost as ze init.
echo "secret" | ze passwd # one-shot pipe
ze passwd # interactive
The output is suitable for direct paste into a YANG password leaf, or as a
shell substitution into ze config set ... password "$(echo s | ze passwd)".
ze cli, ze bgp plugin cli, ze signal, ze config set, ze config edit,
and ze interface migrate accept --user <name> (long) and -u <name>
(short) to override the bootstrap super-admin username. Without the flag,
the CLI uses the username stored in meta/ssh/username by ze init.
| Source | Wins over |
|---|---|
--user/-u flag |
env, zefs |
ze.ssh.username env var |
zefs |
zefs meta/ssh/username |
(default) |
The password for a non-super-admin user must come from ze.ssh.password
(env) or an interactive prompt. There is intentionally no --password
flag (passwords in argv leak into shell history and ps).
See authentication.md for the full multi-user workflow.
Add the HTTPS web interface alongside the BGP daemon. The web server runs on a separate port and provides configuration viewing, editing, and admin commands.
ze start --web 8443 # Start daemon + web on port 8443
ze start --web 8443 --insecure-web # No authentication (forces 127.0.0.1)
ze start --mcp 9718 # Start daemon + MCP server
ze start --web 8443 --mcp 9718 # Both web and MCP
| Flag | Purpose |
|---|---|
--web <port> |
Start web interface on 0.0.0.0:<port> |
--insecure-web |
Disable authentication (forces 127.0.0.1, requires --web) |
--mcp <port> |
Start MCP server on 127.0.0.1:<port> (AI control interface) |
The web server uses a self-signed ECDSA P-256 certificate (persisted in zefs) with SANs for localhost, 127.0.0.1, ::1, and the listen address.
See Web Interface Guide for full usage documentation.
Persistent debug flags stored in ZeFS. Flags survive daemon restarts.
ze debug enable <subsystem|all> # Enable debug logging
ze debug disable <subsystem|all> # Disable debug logging
ze debug show # Show debug state for all subsystems
Three-tier resolution: global override > per-subsystem key > default (off).
Hierarchical prefixes work: ze debug enable bgp enables all bgp.* subsystems.
Low-level blob store management.
ze data import <file>... # Import files into blob
ze data rm <key>... # Remove entries
ze data ls [prefix] # List entries
ze data cat <key> # Print entry content
ze data registered # List all registered key patterns
ze data registered <pattern> # Show details for a key pattern
| Flag | Purpose |
|---|---|
--path <store> |
Blob store path |
Plugin management.
ze plugin <name> [args] # Run plugin CLI handler
ze plugin test # Test plugin schema/config
Generate shell completion scripts for bash, zsh, fish, and nushell. The scripts provide tab completion for subcommands, flags, plugin names, YANG schema modules, show/run command trees, and argument values (address families, log levels).
ze completion bash
ze completion zsh
ze completion fish
ze completion nushell
| Shell | Quick (current session) | Persistent |
|---|---|---|
| Bash | eval "$(ze completion bash)" |
ze completion bash > /etc/bash_completion.d/ze |
| Zsh | eval "$(ze completion zsh)" |
ze completion zsh > ~/.zsh/completions/_ze && autoload -Uz compinit && compinit |
| Fish | ze completion fish | source |
ze completion fish > ~/.config/fish/completions/ze.fish |
| Nushell | ze completion nushell | save -f ($nu.default-config-dir | path join "completions" "ze.nu") |
Add source completions/ze.nu to config.nu |
Environment variable management.
ze env registered # List all registered env vars + log subsystems
ze env registered <key> # Show details for a specific env var
ze env list -v # List with current effective values
ze env get <key> # Show single env var details
| Flag | Purpose |
|---|---|
-v, --verbose |
Show current effective values (list) |
Query DNS, Team Cymru, PeeringDB, and IRR resolution services. Offline tool -- no running daemon required.
ze resolve dns a example.com # IPv4 address records
ze resolve dns aaaa example.com # IPv6 address records
ze resolve dns txt example.com # TXT records
ze resolve dns ptr 8.8.8.8 # Reverse DNS
ze resolve cymru asn-name 13335 # ASN to org name
ze resolve peeringdb max-prefix 13335 # IPv4/IPv6 prefix counts
ze resolve peeringdb as-set 13335 # Registered IRR AS-SETs
ze resolve irr as-set AS-CLOUDFLARE # Expand AS-SET to member ASNs
ze resolve irr prefix AS-CLOUDFLARE # Lookup announced prefixes
| Flag | Subcommand | Purpose |
|---|---|---|
--server <host> |
dns, irr | Override DNS/whois server |
--dns-server <host> |
cymru | Override DNS server for TXT queries |
--url <url> |
peeringdb | Override PeeringDB API base URL |
BGP propagation latency benchmark tool. Separate binary from ze.
ze-perf <command> [flags]
| Command | Purpose |
|---|---|
run |
Run benchmark against a BGP DUT |
report |
Generate comparison report from result files |
track |
Track performance history and detect regressions |
Run a BGP propagation benchmark against a device under test (DUT). Establishes sender and receiver sessions with the DUT, injects routes from the sender, and measures how quickly they propagate through to the receiver.
ze-perf run --dut-addr 172.31.0.2 --dut-asn 65000
ze-perf run --dut-addr 172.31.0.5 --dut-asn 65000 --dut-name gobgp --routes 10000 --json
ze-perf run --dut-addr 172.31.0.2 --dut-asn 65000 --family ipv6/unicast
ze-perf run --dut-addr 172.31.0.2 --dut-asn 65000 --force-mp --repeat 10
DUT flags:
| Flag | Type | Default | Purpose |
|---|---|---|---|
--dut-addr |
string | (required) | DUT BGP address |
--dut-port |
int | 179 | DUT BGP port |
--dut-asn |
int | (required) | DUT autonomous system number |
--dut-name |
string | unknown |
DUT implementation name (appears in results) |
--dut-version |
string | DUT version string |
Sender/receiver flags:
| Flag | Type | Default | Purpose |
|---|---|---|---|
--sender-addr |
string | 127.0.0.1 |
Sender local address |
--sender-asn |
int | 65001 |
Sender autonomous system number |
--sender-port |
int | 0 |
DUT port for sender (0 = use --dut-port) |
--receiver-addr |
string | 127.0.0.2 |
Receiver local address |
--receiver-asn |
int | 65002 |
Receiver autonomous system number |
--receiver-port |
int | 0 |
DUT port for receiver (0 = use --dut-port) |
Benchmark flags:
| Flag | Type | Default | Purpose |
|---|---|---|---|
--routes |
int | 1000 |
Number of routes to inject |
--family |
string | ipv4/unicast |
Address family (ipv4/unicast or ipv6/unicast) |
--force-mp |
bool | false |
Force MP_REACH_NLRI for IPv4 unicast |
--seed |
uint64 | 0 |
Deterministic seed (0 = random) |
--warmup |
duration | 2s |
Warmup delay after session establishment |
--connect-timeout |
duration | 10s |
TCP connection timeout |
--duration |
duration | 60s |
Maximum time to wait for convergence per iteration |
Iteration flags:
| Flag | Type | Default | Purpose |
|---|---|---|---|
--repeat |
int | 5 |
Number of benchmark iterations |
--warmup-runs |
int | 1 |
Warmup iterations (discarded from results) |
--iter-delay |
duration | 3s |
Delay between iterations |
--batch-size |
int | 0 |
UPDATE batch size (0 = single UPDATE per prefix) |
Output flags:
| Flag | Type | Default | Purpose |
|---|---|---|---|
--json |
bool | false |
JSON output |
--output |
string | Output file path (implies --json) |
Exit codes: 0 = success, 1 = error (missing flags, validation failure, benchmark failure).
Generate a comparison report from one or more result JSON files.
ze-perf report result-ze.json result-gobgp.json
ze-perf report --html result-ze.json result-gobgp.json > report.html
| Flag | Type | Default | Purpose |
|---|---|---|---|
--md |
bool | true |
Markdown output |
--html |
bool | false |
HTML output (overrides --md) |
Reads result JSON files produced by ze-perf run --json and generates a
side-by-side comparison table.
Track performance history and detect regressions from an NDJSON file.
ze-perf track history.ndjson
ze-perf track --check history.ndjson
ze-perf track --html history.ndjson > trend.html
ze-perf track --check --threshold-convergence 15 history.ndjson
| Flag | Type | Default | Purpose |
|---|---|---|---|
--md |
bool | true |
Markdown output |
--html |
bool | false |
HTML output (overrides --md) |
--check |
bool | false |
Check for regressions (exit 1 on regression) |
--last |
int | 0 |
Only consider last N entries (0 = all) |
--threshold-convergence |
int | 20 |
Convergence regression threshold (%) |
--threshold-throughput |
int | 20 |
Throughput regression threshold (%) |
--threshold-p99 |
int | 30 |
P99 latency regression threshold (%) |
Exit codes: 0 = no regression (or report mode), 1 = regression detected or error.
Commands sent to the running daemon. Access through three entry points:
| Entry | Access | Usage |
|---|---|---|
ze cli |
Full (interactive) | Exploration, monitoring |
ze show <cmd> |
Read-only | Scripting, dashboards |
Note: Some ze show subcommands run locally without a daemon (version,
bgp decode/encode, env, schema, yang, completion). These are dispatched
via local handlers before attempting SSH connection.
ze cli accepts -c <command> for single-shot execution and
--format <format> (default: yaml).
Many commands take a peer <selector> argument:
| Selector | Example | Description |
|---|---|---|
* |
peer * |
All peers |
| Name | peer upstream1 |
By configured peer name |
| IP address | peer 10.0.0.1 |
By peer IP |
| ASN | peer as65001 |
By remote ASN, case-insensitive (matches all peers with that ASN) |
| Glob | peer 192.168.*.* |
Pattern match |
| Exclusion | peer !10.0.0.1 |
All except this peer |
| ASN exclusion | peer !as65001 |
All except peers with this ASN |
| Command | Access | Purpose |
|---|---|---|
show peer list |
read-only | List all peers (IP, ASN, state, uptime) |
show peer detail <sel> |
read-only | Detailed peer info (config, state, counters, prefix-updated date, prefix-stale warning) |
show peer capabilities <sel> |
read-only | Negotiated capabilities |
show peer statistics <sel> |
read-only | Per-peer update statistics with rates |
show peer history <sel> |
read-only | FSM transition history |
show summary |
read-only | BGP summary table (all peers) |
show summary <afi/safi> |
read-only | Per-family summary: filter to peers that negotiated this AFI/SAFI. Shorthands ipv4, ipv6, l2vpn expand to ipv4/unicast, ipv6/unicast, l2vpn/evpn. Unknown or un-negotiated families reject with the list of families currently negotiated on this daemon. Response adds family + peers-in-family; peers-established is the filtered count |
peer <sel> pause |
write | Pause read loop (flow control) |
peer <sel> resume |
write | Resume read loop |
peer <sel> teardown [<code>] [<msg>] |
write | Graceful close with NOTIFICATION |
peer <sel> flush |
write | Block until all queued updates for peer are on the wire |
| Command | Access | Purpose |
|---|---|---|
show policy test peer <sel> export update <HEX> |
read-only | Dry-run the peer's configured export chain against a BGP UPDATE |
show policy test peer <sel> import update <HEX> |
read-only | Dry-run the peer's configured import chain against a BGP UPDATE |
show policy test peer <sel> export filter <NAME> update <HEX> |
read-only | Dry-run a single named filter against a BGP UPDATE |
The peer selector comes first (peer <sel>, matching show bgp peer <sel> ...), then the direction (import/export), then optional filter <NAME>, then update <HEX>.
<HEX> is a hex-encoded full BGP UPDATE message (including the 19-byte header). The 0x prefix is optional.
Optional: source-asn4 false to test with ASN2 encoding context (default: ASN4). This is what makes AS4_PATH (RFC 6793) the active path carrier.
Output is structured JSON with fields: direction, peer, action (accept/reject/modify), trace (per-filter decisions), text-before, text-after, changed-attrs, and wire-changes (wire-level attribute ops such as AS4_PATH suppressed that the flat filter text cannot express).
This command does not forward routes, update the RIB, populate cache, or mutate peer state.
| Command | Access | Purpose |
|---|---|---|
set system file-descriptors <N|max> |
write | Raise process FD soft limit (Linux only; max sets to hard limit) |
set bgp peer <name> with <config> |
write | Create peer with configuration |
set bgp peer <sel> save |
write | Save running peers to config |
Config keys are parsed from the YANG peer-fields schema via ParseInlineArgs. Container prefixes (remote, local) scope sub-keys. The parser walks the YANG tree to determine how many tokens each field consumes (leaf = name + value, container = name + recurse into children).
| Key | Value | Required | Description |
|---|---|---|---|
remote ip |
IP address | Yes | Peer remote IP address |
remote as |
ASN (uint32) | Yes | Peer AS number |
local as |
ASN (uint32) | No | Local AS override |
local ip |
IP address | No | Local IP for this session |
router-id |
IPv4 address | No | Router ID override |
timer hold-time |
seconds (0-86400) | No | Hold time (default: 90) |
timer connect-retry |
seconds | No | Connect retry interval (default: 120) |
remote connect |
true/false | No | Initiate outbound connections (default: true) |
local accept |
true/false | No | Accept inbound connections (default: true) |
description |
text | No | Peer description |
link-local |
IPv6 address | No | Link-local next-hop |
port |
1-65535 | No | Per-peer listen port |
group-updates |
enable/disable | No | UPDATE grouping |
Example: set bgp peer upstream1 with remote ip 10.0.0.1 remote as 65001 local as 65000 timer hold-time 90 remote connect false
| Command | Access | Purpose |
|---|---|---|
del bgp peer <sel> |
write | Remove peer |
| Command | Access | Purpose |
|---|---|---|
update bgp peer <sel> prefix |
write | Update prefix maximums from PeeringDB |
peer <sel> update text <attrs> nlri <family> <op> <prefixes>
peer <sel> update hex <hex-data>
peer <sel> update b64 <b64-data>
peer <sel> raw [<type>] <encoding> <data>
Text format attributes:
| Attribute | Syntax |
|---|---|
origin |
origin set igp / egp / incomplete |
nhop |
nhop set 192.168.1.1 or nhop set self |
med |
med set 100 |
local-preference |
local-preference set 200 |
as-path |
as-path set [ 65001 65002 ] |
community |
community set [ 65000:100 no-export ] |
large-community |
large-community set [ 65000:1:1 ] |
extended-community |
extended-community set [ rt:65000:100 ] |
NLRI operations: nlri <family> add <prefixes>, nlri <family> del <prefixes>,
nlri <family> eor.
| Command | Access | Purpose |
|---|---|---|
show bgp rib status |
read-only | RIB summary (peer count, routes, families) |
show bgp rib |
read-only | Stream Adj-RIB-In and Adj-RIB-Out routes |
show bgp rib | received |
read-only | Stream received routes only |
show bgp rib | advertised |
read-only | Stream advertised routes only |
show bgp rib | peer <selector> |
read-only | Stream routes for one peer selector |
show bgp rib best |
read-only | Best-path per prefix |
show bgp rib best status |
read-only | Best-path computation status |
rib clear in <selector> |
write | Clear Adj-RIB-In (* for all peers) |
rib clear out <selector> [family] |
write | Regenerate and re-advertise Adj-RIB-Out (* for all peers, optional family filter) |
rib inject <peer> <family> <prefix> [attrs...] |
write | Insert route into Adj-RIB-In as if received from peer |
rib withdraw <peer> <family> <prefix> |
write | Remove route from Adj-RIB-In |
rib rpf <family> <source-addr> |
read | RPF lookup: longest-prefix-match against Loc-RIB for CIDR families |
| Command | Access | Purpose |
|---|---|---|
healthcheck show |
read-only | JSON summary of all healthcheck probes |
healthcheck show <name> |
read-only | Detailed status of a single probe |
healthcheck reset <name> |
write | Withdraw route, reset FSM to INIT, immediate re-check. Error if DISABLED. |
| Command | Access | Purpose |
|---|---|---|
show bmp sessions |
read-only | Show active BMP receiver sessions (router address, sysName, uptime) |
show bmp peers |
read-only | Show monitored BGP peers (AS, BGP ID, up/down status) |
show bmp collectors |
read-only | Show BMP sender collector connection status |
show bmp rib |
read-only | Show BMP-monitored routes |
| Command | Access | Purpose |
|---|---|---|
commit start <name> |
write | Begin named update window |
commit end <name> |
write | Flush queued updates |
commit eor <name> |
write | Flush updates and send End-of-RIB |
commit show <name> |
read-only | Show queue status |
commit rollback <name> |
write | Discard queued updates |
commit withdraw <name> route <prefix> |
write | Withdraw prefix from window |
commit list |
read-only | List active commits |
Commit names must not collide with action keywords (list, start, end,
eor, rollback, show, withdraw). The old grammar commit <name> <action>
is accepted with a deprecation warning but does not work when the name equals
a keyword.
| Command | Access | Purpose |
|---|---|---|
cache list |
read-only | List cached message IDs |
cache retain <id> |
write | Pin in cache (prevent eviction) |
cache release <id> |
write | Release from cache |
cache expire <id> |
write | Remove immediately |
cache forward <id> <peer-sel> |
write | Re-inject UPDATE to peer(s) |
Batch operations: cache forward <id1>,<id2> <selector>.
| Command | Access | Purpose |
|---|---|---|
show static |
read-only | Show all configured static routes in JSON: prefix, action, next-hops with address/weight/BFD status, metric, tag |
The static route plugin programs routes directly to the kernel (netlink multipath) or VPP. It auto-loads when the config contains a static { } section. See Static Routes Guide.
| Command | Access | Purpose |
|---|---|---|
sysctl show |
read-only | Show all active sysctl keys with value, source (config/transient/default), and persistence |
sysctl list |
read-only | List all known sysctl keys with descriptions and types |
sysctl describe <key> |
read-only | Show detail for one key: description, type, range, current value, source |
sysctl set <key> <value> |
write | Set a transient sysctl value (overrides defaults, blocked by config) |
sysctl list-profiles |
read-only | List all registered sysctl profiles (built-in and user-defined) with key counts |
sysctl describe-profile <name> |
read-only | Show detail for one profile: description, all key/value pairs |
The sysctl plugin manages kernel tunables with three-layer precedence: config (persistent, from YANG) wins over transient (CLI sysctl set), which wins over defaults (plugin-declared via EventBus). Original values are restored on clean daemon stop.
Config example: sysctl { setting net.ipv4.conf.all.forwarding { value 1; } }
Named profiles group co-dependent tunables for common use cases. Apply them per interface unit: sysctl-profile [ dsr hardened ]. Built-in profiles: dsr, router, hardened, multihomed, proxy. User-defined profiles declared in sysctl { profile <name> { ... } }.
When fib-kernel is loaded, it automatically enables IPv4 and IPv6 forwarding as defaults.
| Command | Access | Purpose |
|---|---|---|
show l2tp |
run | L2TP subsystem summary (tunnel/session counts) |
show l2tp tunnels |
run | List all active L2TP tunnels |
show l2tp tunnel <tid> |
run | Show one tunnel by local tunnel ID |
show l2tp sessions |
run | List all active L2TP sessions |
show l2tp session <sid> |
run | Show one session by local session ID |
show l2tp statistics |
run | Protocol counters |
show l2tp listeners |
run | Bound UDP listener endpoints |
show l2tp config |
run | Effective runtime configuration |
show l2tp observer <sid> |
run | Per-session event ring snapshot (timestamps, types, RTT, reasons) |
show l2tp observer all |
run | Summary of all active session event rings |
show l2tp cqm <login> |
run | Per-login CQM bucket history (100s echo RTT/loss aggregates) |
show l2tp cqm summary |
run | Aggregate CQM state across all tracked logins |
show l2tp echo <login> |
run | Current echo state for a login (RTT, loss ratio, interval) |
show l2tp reliable <tid> |
run | Reliable transport window state (Ns, Nr, cwnd, retransmits) |
clear l2tp tunnel teardown <tid> |
run | Send StopCCN for one tunnel |
clear l2tp tunnel teardown-all |
run | Send StopCCN for every tunnel |
clear l2tp session teardown <sid> [reason <text...>] [cause <code>] |
run | Send CDN for one session with optional audit reason and disconnect cause |
clear l2tp session teardown-all |
run | Send CDN for every session |
The clear l2tp session teardown command accepts optional keyword arguments:
reason <text...>: free-text audit reason, recorded in the per-session event ringcause <code>: RADIUS Disconnect-Cause value (uint16), recorded alongside the reason
| Command | Mode | Description |
|---|---|---|
show pppoe |
run | PPPoE subsystem summary (session/interface counts) |
show pppoe sessions |
run | List all active PPPoE sessions |
show pppoe session <sid> |
run | Show one session by session ID |
show pppoe statistics |
run | Per-interface session counts and limits |
show pppoe interfaces |
run | Configured PPPoE access interfaces |
The web interface at /l2tp provides session management and CQM graphing.
| URL | Method | Purpose |
|---|---|---|
/l2tp |
GET | Session list with sortable columns |
/l2tp/<sid> |
GET | Session detail: state, PPP options, CQM chart, event timeline, disconnect |
/l2tp/<login>/samples |
GET | CQM buckets as columnar JSON (uPlot data shape) |
/l2tp/<login>/samples.csv |
GET | CQM buckets as CSV download |
/l2tp/<login>/samples/stream |
GET | SSE stream pushing new CQM buckets every 100s |
/l2tp/<sid>/disconnect |
POST | Disconnect session (requires reason form field; optional cause) |
Disconnect is gated by authz: the clear prefix is denied in the built-in read-only profile.
The CQM chart uses vendored uPlot rendered client-side with CSS color variables
(--color-l2tp-established, --color-l2tp-negotiating, --color-l2tp-down).
| Command | Access | Purpose |
|---|---|---|
l2tp decode [--pretty] |
offline | Decode a hex L2TPv2 control message on stdin and emit JSON on stdout |
ze l2tp decode runs without a daemon. Input is ASCII hex (whitespace
allowed); output is a JSON object with a parsed header and an avps
array. Each AVP carries its vendor, numeric type, RFC 2661 catalog name
(when vendor 0), flag booleans, and the raw value as lowercase hex. Use
--pretty for indented output.
Example:
echo c8020044... | ze l2tp decode --pretty
Exit code is 0 on successful parse, 1 on invalid hex, truncated header, or malformed AVPs; stderr carries the reason.
bgp monitor [peer <sel>] [event <types>] [direction <dir>]
| Filter | Values |
|---|---|
peer |
IP address, * |
event |
update, open, notification, keepalive, refresh, state, negotiated (comma-separated) |
direction |
sent, received |
Streaming command: use in interactive ze cli or via SSH.
monitor system netlink [route|link|address|all]
Stream kernel netlink events as one JSON line per event. Replaces ip monitor on gokrazy appliances. Linux only.
| Group | Events |
|---|---|
route |
Route add/delete with prefix, gateway, table, protocol |
link |
Interface up/down/create/delete with name, state, MTU, MAC |
address |
Address add/remove with CIDR, interface |
all |
All of the above (default when no group specified) |
Streaming command: use in interactive ze cli or via SSH. Press Esc to stop.
monitor interface rate [<name>]
Stream per-second interface rate data as JSON lines (one line per tick, 1s interval). Without a name, streams all interfaces sorted by name. With a name, streams only that interface.
Each JSON line contains: name, rx-bps, tx-bps, rx-pps, tx-pps, and the raw kernel stats snapshot (8 counters). Rate values are computed from raw kernel counter deltas; counter wraps produce 0 rather than negative spikes.
Streaming command: use in interactive ze cli or via SSH. Press Esc to stop.
| Command | Access | Purpose |
|---|---|---|
metrics show |
read-only | Prometheus text format metrics |
metrics list |
read-only | List metric names |
metrics pool |
read-only | Per-attribute-pool occupancy, dedup rates, and aggregate totals (13 BGP pools) |
| Command | Access | Purpose |
|---|---|---|
log show |
read-only | List subsystems with current log levels |
log set <subsystem> <level> |
write | Set log level at runtime |
Levels: debug, info, warn, err, disabled.
| Command | Access | Purpose |
|---|---|---|
bgp plugin encoding <json|text> |
write | Set event encoding |
bgp plugin format <hex|base64|parsed|full> |
write | Set wire format display |
bgp plugin ack <sync|async> |
write | Set ACK timing |
| Command | Access | Purpose |
|---|---|---|
help |
read-only | List available subcommands |
command-list |
read-only | List all commands with descriptions |
command-help <name> |
read-only | Detailed help for a command |
event-list |
read-only | List available event types |
Inside ze cli:
| Feature | Syntax |
|---|---|
| Pipe: filter lines | show peer list | match established |
| Pipe: count | show peer list | count |
| Pipe: table format | show bgp rib | table |
| Pipe: text format | show peer list | text |
| Pipe: JSON pretty | show peer list | json |
| Pipe: JSON compact | show peer list | json compact |
| Pipe: NDJSON | show peer list | ndjson |
| Pipe: YAML | show peer list | yaml |
| Pipe: reverse DNS | show traceroute 8.8.8.8 | resolve |
| Pipe: ASN lookup | show traceroute 8.8.8.8 | origin |
| Pipe: streaming log | monitor traceroute 8.8.8.8 | log |
| Pipe: disable paging | show peer list | no-more |
| Set default format | set cli format json (session override) |
| Show current format | set cli format (no argument) |
| Tab completion | Contextual command/argument completion |
The daemon handles these Unix signals directly:
| Signal | Effect |
|---|---|
SIGHUP |
Reload configuration |
SIGTERM / SIGINT |
Graceful shutdown |
SIGUSR1 |
Dump status to stderr |
Chaos monkey for testing Ze BGP route server propagation.
| Flag | Description |
|---|---|
--mcp <addr:port> |
Start chaos MCP server for AI queries (e.g. :8001) |
--ze-mcp <port> |
Inject Ze MCP server port into generated config |
--ai-help |
Print chaos MCP tool definitions as JSON and exit |
ze-chaos --mcp :8001 --web :8000 --peers 4 # MCP + web dashboard
ze-chaos --ze-mcp 9718 --peers 4 # Inject MCP into Ze config
ze-chaos --ai-help # Print tool schemas