Skip to content

Routing API (BGP and OSPF)

The router runs BGP and OSPF through BIRD 2. These endpoints read and change its routing settings; the router writes BIRD’s configuration from them, checks it with BIRD and loads it. How it works: BGP and OSPF. The CLI equivalents are dtvsol bgp … and dtvsol ospf …. Authentication and errors: see the API overview.

A change that could cut the router off (every operation except the blackholes, confirm and undo) is loaded with a 120-second timer while BGP or OSPF is on: it answers "pending": true and a deadline, and is undone by itself unless POST /bgp/confirm comes first. While a change waits, the other changes answer 409.

The settings (without the passwords), each peer with its session as BIRD has it, OSPF with its neighbours, and what is wrong.

Terminal window
curl -s "http://ROUTER-IP:8880/bgp" -H "X-API-Key: YOUR_API_KEY"
{
"ok": true,
"enabled": true,
"asn": 65010,
"router_id": "XXX.XXX.XXX.2",
"announce": ["XXX.XXX.XXX.0/22", "XXXX:XXXX::/32"],
"blackhole": [],
"peers": [
{
"name": "isp-a", "ip": "XXX.XXX.XXX.1", "asn": 64500, "type": "upstream",
"routes": "default", "role": "primary", "enabled": true, "description": "",
"password_set": false, "blackhole_community": "64500:666",
"state": "Established", "up": true, "since": "10:00:05.123", "info": "Established",
"last_error": null, "received": 1, "sent": 2, "filtered": 0, "best": 1
}
],
"ospf": {
"enabled": true, "area": "0.0.0.0", "originate_default": true, "accept_default": false,
"interfaces": [{"name": "vlan20", "cost": 10, "passive": false, "neighbors_full": 1}],
"neighbors": [{"proto": "ospf4", "router_id": "10.0.0.3", "state": "Full/DR", "iface": "vlan20", "ip": "10.0.0.3"}],
"protocols": [{"name": "ospf4", "state": "up", "info": "Running", "since": "10:00:00.000"}]
},
"installed": true,
"bird_error": null,
"problems": [],
"settings": { },
"kernel_metric": 32,
"pending": null
}
Field Meaning
peers[].state BIRD’s BGP state (Established when the session is up; Active, Connect, Idle… otherwise), or null while BGP is off.
peers[].received, sent Routes received from the peer and sent to it, summed over its channels.
peers[].last_error BIRD’s last error of the session (e.g. Socket: Connection refused).
ospf.interfaces[].neighbors_full OSPF neighbours in state Full on the interface.
installed BIRD is installed.
bird_error Why BIRD could not be asked, or null.
problems What is wrong in the settings (a change that leaves one is refused).
peers[].bfd, bfd_state BFD on the session, and its state (Up, Down, Init…) or null.
rpki {enabled, status: {data, age_s, vrps, stale}}: RPKI on or off, and the validated data (its age in seconds, how many route origins).
pending The change waiting for its confirm: {deadline, what, by} (deadline in Unix seconds), or null.

The configuration BIRD gets, as text, with the passwords replaced by ********: {"ok": true, "config": "…", "file": "/etc/bird/bird.conf"}.

Every change is POST /bgp/<op> with a JSON body. The answer is {"ok": true, "message": "…", "pending": true|false, "deadline": …}, or {"ok": false, "error": "…"} with 400 (wrong input or settings with problems — nothing changed), 404 (unknown operation), 409 (a change is waiting, or BIRD is not installed) or 500.

This router’s BGP settings. Any of:

Name In Type Notes
asn body integer Your AS number.
router_id body string An IPv4 address of this router (BGP and OSPF).
enabled body boolean BGP on or off.
rpki body boolean RPKI on or off: drop routes with a proven false origin from full-table upstreams (the validator’s timer follows).

Adds a peer, or changes the peer of that name. On a change, the fields not sent stay as they are (the password too).

Name In Type Notes
name body string 1–32 letters, digits, -, _. Required.
ip body string The peer’s IPv4 or IPv6 address. Required.
asn body integer The peer’s AS. Required.
type body string upstream (default) or ibgp (another Super Router, your own AS).
routes body string Upstreams: default (default route only; the default) or full (the full table).
role body string Upstreams: primary (default) or backup.
password body string TCP MD5 password; stored encrypted, never shown.
blackhole_community body string The upstream’s blackhole community, as:n (e.g. 65535:666). Empty removes it.
max_prefix body integer Prefix limit (default: 16 for a default route, 1,500,000 IPv4 / 400,000 IPv6 for a full table).
multihop body integer For a peer that is not directly connected: the TTL.
bfd body boolean BFD on the session (the peer runs BFD too): a dead peer seen in under a second.
enabled body boolean Default true.
description body string Up to 80 characters.

{"name": "…"} — removes the peer.

{"name": "…"} — starts the peer’s session again.

{"name": "…"} — stops the peer’s session, keeping the peer.

{"prefix": "XXX.XXX.XXX.0/22"} — a public IPv4 block from /8 to /24, or IPv6 from /16 to /48.

{"prefix": "…"} — stops announcing it.

{"ip": "XXX.XXX.XXX.66"} — one public address, sent as a /32 (/128) with each upstream’s blackhole community, and dropped by this router. Loaded at once, without the timer.

{"ip": "…"} — removes the blackhole.

Any of:

Name In Type Notes
enabled body boolean OSPF on or off.
area body string A number or a dotted quad; 0.0.0.0 by default.
originate_default body boolean Tell the OSPF routers our (BGP) default route.
accept_default body boolean Take a default route from OSPF.

{"name": "vlan20", "cost": 10, "passive": false} — adds an interface of this router to OSPF, or changes it. passive: its network is announced, no neighbour is looked for on it.

{"name": "…"} — removes the interface from OSPF.

Keeps the change that is waiting.

Undoes the change that is waiting, at once.

Terminal window
curl -s -X POST "http://ROUTER-IP:8880/bgp/peer-add" -H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "isp-a", "ip": "XXX.XXX.XXX.1", "asn": 64500, "routes": "default", "role": "primary"}'
curl -s -X POST "http://ROUTER-IP:8880/bgp/confirm" -H "X-API-Key: YOUR_API_KEY"

This site was written with the help of AI and checked by our team.