BGP Edge Routing
Gateway nodes run an integrated BGP speaker that connects your fabric to the outside world. You configure peer sessions, announce your managed-network prefixes upstream, optionally import external routes, and filter routes with prefix-lists and route-maps — all through cenvero-str-ctl.
How it fits together
A node at the edge of the fabric speaks BGP upstream. It speaks eBGP to one or more upstream routers or route reflectors, announcing the subnets of your internal networks so external hosts can reach them. Inbound prefixes learned from peers are installed into the kernel routing table and become reachable from within the fabric.
What travels in each direction
Two separate flows, and confusing them is the usual cause of "the session is up but nothing works":
Out — what you announce. Nothing leaves automatically. A prefix is advertised only once you announce it, so bringing a session up publishes nothing on its own. Until you announce, your peer has no idea your networks exist and traffic will not come to you.
In — what you learn. Prefixes your peers advertise are accepted, subject to any filters you set, and installed as routes so workloads inside the fabric can reach them. A peer that sends you nothing leaves you with a working session and no new routes, which is normal if it is only meant to receive.
A session being Established means the two speakers are talking. It does not mean any route has been exchanged in either direction — check what is actually being carried rather than inferring it from the session state.
How a session comes up
A peer moves through a sequence of states, and knowing them makes the difference between waiting and debugging:
| State | Meaning |
|---|---|
| Idle | Not trying yet, or backing off after a failure before the next attempt. |
| Connect / Active | Trying to reach the peer. Sitting here means the peer is not answering — check reachability and that it is expecting you. |
| OpenSent / OpenConfirm | Connected; the two sides are agreeing terms. Sitting here usually means a mismatch, most often the AS number each side expects of the other. |
| Established | Working. Routes can now be exchanged. |
Both ends may try to connect to each other at the same time — normal when two Stratum nodes peer directly. Two connections briefly exist and one is discarded automatically, which is expected and needs no configuration.
Once established, the two exchange keepalives (every 30 seconds by default). If nothing is heard for the hold time (90 seconds by default) the session is considered dead and torn down, and the routes learned through it are withdrawn. Lower both if you need failure detected faster, at the cost of more chatter — they are negotiated, so the peer must agree.
Peers that keep returning to Idle are usually being rejected rather than failing to connect. Check the AS numbers on both sides first; that is the most common cause.
For redundant deployments with a pair of Gateways, both nodes can establish their own peer sessions and announce the fabric prefixes. The shared VIP is held by exactly one Gateway at a time (priority-based active/standby); Stratum's HA mechanism moves the VIP to the surviving node if the active Gateway goes down. See Gateway High Availability.
Configuring a peer session
sudo cenvero-str-ctl bgp peer add '{"peer_addr":"198.51.100.1","peer_as":65001,"local_as":65100,"md5_key":"mysecretpass"}'
The neighbour is a single JSON object. peer_addr, peer_as, and local_as are required; the rest are optional:
| Field | Description |
|---|---|
peer_addr | Upstream router's IP address |
peer_as | Upstream router's AS number |
local_as | This node's AS number |
md5_key | BGP TCP-MD5 authentication key (optional but recommended; never returned in reads) |
hold_time | BGP hold timer in seconds (default 90) |
keepalive_interval | BGP keepalive interval in seconds (default 30) |
bfd_enabled | Enable BFD fast failure detection for this peer (true/false) |
bfd_interval_ms | BFD min-tx/min-rx interval in milliseconds |
bfd_multiplier | BFD detect multiplier (failure-detection time is interval × multiplier) |
List configured peers and their session state:
cenvero-str-ctl bgp peer list
PEER PEER-ASN LOCAL-ASN STATE PREFIXES-RX PREFIXES-TX
198.51.100.1 65001 65100 Established 12 3
198.51.100.2 65002 65100 Established 8 3
Remove a peer session:
sudo cenvero-str-ctl bgp peer remove 198.51.100.1
Announcing prefixes
Tell Stratum which internal prefixes to advertise to peers:
sudo cenvero-str-ctl bgp announce 10.20.0.0/24
sudo cenvero-str-ctl bgp announce 10.30.0.0/24
Announcements take effect as soon as they are added. You can also announce a summary prefix that covers multiple networks:
sudo cenvero-str-ctl bgp announce 10.20.0.0/20
List what you are announcing:
cenvero-str-ctl bgp announcements
Withdraw a prefix (peers are notified immediately):
sudo cenvero-str-ctl bgp withdraw 10.20.0.0/24
Importing external prefixes
By default, prefixes learned from peers are installed in the kernel routing table and are reachable from within the fabric. You can filter what gets imported.
Filtering is expressed as prefix-lists and route-maps, then bound to a neighbour as an import (or export) policy — each is a single JSON object. First define a prefix-list of the CIDRs you care about (entries are matched in order; each has an action of allow or deny and optional ge/le length bounds):
sudo cenvero-str-ctl bgp prefix-list add '{"name":"customer-routes","entries":[{"prefix":"172.16.0.0/12","action":"allow","le":24},{"prefix":"0.0.0.0/0","action":"deny"}]}'
Reference that prefix-list from a route-map, which decides what to do with a matching route and can set attributes such as local-preference:
sudo cenvero-str-ctl bgp route-map add '{"name":"import-filter","entries":[{"seq":10,"action":"allow","match_prefix":"customer-routes","set_local_pref":200}]}'
Bind the route-map to a neighbour as its import policy (use export for the outbound direction):
sudo cenvero-str-ctl bgp policy import 198.51.100.1 import-filter
Checking RIB and FIB
Inspect the BGP routing information base:
cenvero-str-ctl bgp rib
PREFIX NEXT-HOP AS-PATH MED LOCAL-PREF SOURCE
10.20.0.0/24 0.0.0.0 - - - local
0.0.0.0/0 198.51.100.1 65001 0 100 ebgp
172.16.0.0/12 198.51.100.1 65001 0 100 ebgp
Show only routes installed in the kernel forwarding table:
cenvero-str-ctl bgp fib
RPKI route-origin validation
Route-Origin Validation (ROV, RFC 6811) checks each prefix a peer advertises against Resource Public Key Infrastructure (RPKI) data, so you can tell whether the AS that originated a route is actually authorized to announce it. Stratum learns the set of validated prefix-to-origin records (the VRP set) from an external RPKI-to-Router (RTR, RFC 8210) cache — such as Routinator, rpki-client, or StayRTR — and classifies every received route as:
- valid — a matching record authorizes this prefix from this origin AS.
- invalid — a record covers the prefix but the origin AS or prefix length does not match, a likely mis-origination or hijack.
- not-found — no record covers the prefix.
ROV is off by default and fail-safe. With no RTR configured, an unreachable cache, or stale data, the VRP set is empty, every route resolves to not-found, and BGP behaves exactly as it would without ROV — an RTR outage can never cause a route to be rejected. By default ROV only marks each route with its validation state and does not change route selection; the opt-in reject-invalid policy additionally drops RPKI-invalid routes before they enter the routing table.
Point Stratum at your RTR cache and start validating:
sudo cenvero-str-ctl bgp rpki configure 192.0.2.10:323 --reject-invalid
| Argument / flag | Description |
|---|---|
<rtr-addr> | Address (host:port) of the RTR cache to connect to |
--reject-invalid | Drop RPKI-invalid routes instead of only marking them (optional) |
Check the RTR session state, VRP count, and per-outcome validation tallies:
cenvero-str-ctl bgp rpki status
Test how a given prefix and origin AS would classify against the current VRP set:
cenvero-str-ctl bgp rpki validate 192.0.2.0/24 64500
Start or stop ROV using the configured RTR address; disabling clears the VRP set and reverts to plain BGP:
sudo cenvero-str-ctl bgp rpki enable
sudo cenvero-str-ctl bgp rpki disable
EVPN address family
Stratum's BGP speaker can carry the EVPN (Ethernet VPN, RFC 7432) address family — L2VPN/EVPN over MP-BGP — integrated with the VXLAN overlay (EVPN-VXLAN, RFC 8365). It exchanges two route types with EVPN-capable peers:
- Type 2 (MAC/IP) — advertises the MAC (and optional IP) of a local overlay endpoint, so peers learn which VTEP a MAC lives behind.
- Type 3 (Inclusive Multicast) — advertises the local VTEP so peers know where to send broadcast, unknown-unicast, and multicast traffic for a VNI.
Each route carries a Route Distinguisher and Route Target, and the 24-bit VXLAN VNI is encoded in the MPLS label field.
Scope — control plane only. EVPN in Stratum is a route-exchange feature: it learns remote MAC-to-VTEP and VTEP bindings over BGP and maintains the EVPN route tables, but it does not program those learned routes into the overlay forwarding path. Use it to exchange and inspect MAC/VTEP reachability, and configure VXLAN peers explicitly for forwarding (see Clustering Overview).
EVPN is off by default and backward-compatible: while disabled, the EVPN address family is not advertised and BGP behaves exactly like the plain IPv4/IPv6-unicast speaker.
Enable EVPN, advertising a local VTEP and route distinguisher:
sudo cenvero-str-ctl bgp evpn enable --vtep 10.0.0.1 --rd 65000:100
| Flag | Description |
|---|---|
--vtep | Local VTEP source IP advertised as the EVPN next hop |
--rd | Route distinguisher, e.g. 65000:100 or 10.0.0.1:100 |
Register a local MAC (and optional IP) under a VNI so it is advertised as a Type 2 route:
sudo cenvero-str-ctl bgp evpn local-mac add 10100 aa:bb:cc:dd:ee:ff 192.0.2.10
Inspect EVPN state and the local plus learned routes:
cenvero-str-ctl bgp evpn status
cenvero-str-ctl bgp evpn show
Disable EVPN — it stops advertising the address family and withdraws the routes it announced:
sudo cenvero-str-ctl bgp evpn disable
See also
- Gateway High Availability — redundant Gateway BGP speakers and failover.
- Load Balancer — combine BGP with L4 VIPs for published external services.
- Zero-Trust Firewall — north-south traffic from BGP peers passes through the firewall.