EXABGP.CONF(5)
π NAME π
exabgp.conf β bestie, this is the file that holds the BGP configuration for exabgp(1). It's the one that tells exabgp who its neighbors are and what it's allowed to say to them. Main character energy, fr fr. π¦
β¨ DESCRIPTION β¨
So like, exabgp.conf is where you spell out the BGP neighbor configuration for exabgp. That's the whole vibe. Every neighbor, every template, every route you're manifesting into the BGP session β it all lives here. π
π CONFIGURATION FILE SYNTAX π
Okay so here's the entire shape of the file, and I am not skipping a single line of it because everything here matters, no cap:
template {
neighbor <template-name> {
<neighbor-configuration>;
// Suitable for setting common attributes
// shared by more than one actual neighbor.
// Can use basically any of the attributes
// in the below neighbor configuration
}
}
// Most attributes / settings are optional
neighbor <ip-address> {
description <text>;
inherit <template-name>; // from previously defined template
router-id <router-id>;
host-name <hostname>;
domain-name <domain-name>;
local-address <ip-address>;
local-as <asn>;
peer-as <asn>;
hold-time <seconds>;
rate-limit <enable | disable>;
manual-eor <truthvalue>;
passive <truthvalue>;
listen <ip-address>;
group-updates <truthvalue>;
auto-flush <truthvalue>;
adj-rib-in <truthvalue>;
adj-rib-out <truthvalue>;
md5-password <md5-secret>;
md5-base64 <auto | true | false>;
md5-ip <ip-address>;
capability {
add-path <disable | send | receive | send/receive>;
asn4 <enable | disable>;
graceful-restart <time-in-seconds>;
multi-session <enable | disable>;
operational <enable | disable>;
route-refresh <enable | disable>;
extended-message <enable | disable>;
}
family {
all; // default, or a list of the below
minimal; // use AFI/SAFI required to announce routes in config
ipv4 unicast;
ipv4 multicast;
ipv4 nlri-mpls;
ipv4 mpls-vpn;
ipv4 flow;
ipv4 flow-vpn;
ipv6 unicast;
ipv6 flow;
ipv6 flow-vpn;
}
nexthop {
ipv4 unicast ipv6;
ipv4 multicast ipv6;
ipv4 mpls-vpn ipv6;
ipv4 nlri-mpls ipv6;
ipv6 unicast ipv4;
ipv6 multicast ipv4;
ipv6 mpls-vpn ipv4;
ipv6 nlri-mpls ipv4;
}
add-path {
ipv4 unicast;
ipv4 multicast;
ipv4 nlri-mpls;
ipv4 mpls-vpn;
ipv4 flow;
ipv4 flow-vpn;
ipv6 unicast;
ipv6 flow;
ipv6 flow-vpn;
}
api {
processes [ <process-name-list> ];
}
static {
route <ip-address>/<prefixlength> {
next-hop <ip-address>; // only mandatory attribute
origin ( IGP | EGP | INCOMPLETE );
as-path [ <as-sequence-asn> | ( <as-set ) ];
as-sequence;
med <med>;
aigp <aigp>;
local-preference <preference>;
atomic-aggregate;
aggregator <asn>:<ip-address>;
path-information <ip-address>;
community ( <community> | [ <community> <community> ... ] );
large-community ( <large-community> | [ <large-community> ... ] );
originator-id <ip-address>;
cluster-list ( <ip-address> | [ <ip-address> <ip-address> ... ] );
extended-community ( <extended-community> |
[ <extended-community> ... ] );
split /<prefixlength>;
label ( <label> | [ <label> <label> ... ] );
rd <route-distinguisher>;
watchdog <watchdog-name>;
bgp-prefix-sid ( [<label-index-value>] |
[ <label-index-value>, [ ( <srgb-base_1>,<srgb-range_1> ), ... ] ]);
withdraw;
}
// or alternatively
route <ip-address>/<prefixlength> <attribute-sequence>;
// where <attribute-sequence> is a sequence of
// any of the attributes above
}
flow {
route <route-name> {
rd <route-distinguisher>;
next-hop <ip-address>; // for redirect-to-nexthop
match {
// one or more match terms
source <ip-address>/<prefixlength>;
destination <ip-address>/<prefixlength>;
port <portnumber>;
source-port <portnumber>;
destination-port <portnumber-expression>;
protocol [ udp | tcp ]; // IPv4 only
next-header [ udp | tcp ]; // IPv6 only
tcp-flags [ fin | syn | rst | push | ack | urg | ece | cwr | ns ];
icmp-type [ echo-reply | echo-request | info-reply |
info-request | mask-reply | mask-request |
parameter-problem | redirect | router-advertisment |
router-solicit | source-quench | time-exceeded |
timestamp | timestamp-reply | unreachable ];
icmp-code [ communication-prohibited-by-filtering |
destination-host-prohibited |
destination-host-unknown |
destination-network-unknown |
fragmentation-needed | host-precedence-violation |
ip-header-bad | network-unreachable |
network-unreachable-for-tos | port-unreachable |
redirect-for-host | redirect-for-network |
redirect-for-tos-and-host |
redirect-for-tos-and-net |
required-option-missing | source-host-isolated |
source-route-failed |
ttl-eq-zero-during-reassembly |
ttl-eq-zero-during-transit ];
fragment [ dont-fragment | is-fragment |
first-fragment | last-fragment ];
// fragment is IPv4 only, poorly tested
dscp <dscp-value>;
traffic-class <traffic-class>;
packet-length <packet-length-expression>;
flow-label <flow-label-expression>; // IPv6 only
}
then {
// one action only
accept;
discard;
rate-limit <ratelimit>;
redirect ( <route-distinguisher> | <ip-address> );
redirect-to-nexthop; // Ref. next-hop above
redirect-to-nexthop-ietf <ip-address>;
copy <ip-address>;
mark <mark>;
action ( sample | terminal | sample-terminal );
community;
large-community;
extended-community;
}
}
}
l2vpn {
vpls <site-name> {
endpoint ( <vpls-endpoint> (integer) );
offset ( <block-offset> (integer) );
size ( <block-size> (integer) );
base ( <label-base> (integer) );
name <route-name>;
next-hop <ip-address>;
origin ( IGP | EGP | INCOMPLETE );
as-path [ <as-sequence-asn> | ( <as-set ) ];
med <med>;
local-preference <preference>;
rd <route-distinguisher>;
community ( <community> | [ <community> <community> ... ] );
large-community ( <large-community> |
[ <large-community> ... ] );
originator-id <ip-address>;
cluster-list [ <ip-address> <ip-address> ... ];
// l2info: encaps:control-flag:mtu:site-preference
extended-community ( <extended-community> |
[ <extended-community> ... ] );
withdraw;
}
}
}
process <process-name> {
run <command>;
encoding <text | json>;
}
π¨ Okay listen, this one is so important bestie: multi-line sections really do need to be written as multiple lines. The opening one ends with a{, and then you close it with a line that has just a}on its own. No sneaking it all onto one line, no trying to be clever. The parser will simply not be serving cunt and your config will break. π
π SEE ALSO π
exabgp(1)β go read it, it's the whole reason this file exists π«Ά
π CAVEATS π
Okay so, real talk, there's some stuff here that just... isn't documented yet. Not me being dramatic, it's literally in the manual:
- Default values ought to be documented. Right now they aren't. π
- The functionality and semantics of the
process/apisections ought to be documented too. Also not yet. - The
healthcheckmodule ofexabgpis perhaps deserved of its own man page. (As it should, honestly β give the girl her own spotlight. π)
And that's the whole page, bestie!! π This one landed in the world on October 14, 2022, and it's filed under EXABGP.CONF(5) in the manual pages. Go forth and configure your neighbors responsibly β slay. πβ¨π¦
π¦ where this page comes from
- fedora 44: exabgp 5.0.5-1.fc44 Β· BSD-3-Clause
- fedora 44: exabgp 5.0.9-1.fc44 Β· BSD-3-Clause
- ubuntu resolute: exabgp 5.0.8-1 Β· BSD-3-Clause
- ubuntu stonking: exabgp 5.0.8-1 Β· BSD-3-Clause
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms