Before this change, a session on which ADD-PATH (RFC 7911) was
negotiated in the sending direction was sent path identifiers, but only
the best route for each prefix. A route collector such as bgp.tools
wants every route a router has accepted, from every neighbor, and from
one session: without this the collector saw one path per prefix, nearly
always the same neighbor's.
This change adds `all_paths` to the export policy. On a session with it,
and ADD-PATH send negotiated for a family, every accepted route for a
prefix of that family is advertised, each with a path identifier of its
own; for a family without ADD-PATH send the best route goes as before.
`all_paths` needs `learned_routes` (a configuration error otherwise) and
the peer's `add_path` to offer sending. The export policy, the role
rules, the well-known communities and the export limits apply to every
route alike, and the export limits count every route.
Implementation, in the advertiser:
* An exporter with `all_paths` follows the table's journal of all routes
(`RibTable::reader_of_all_routes`, until now unused) instead of the
best-route journal, and is given all the routes of a prefix whenever
one of them changes (`News::Routes`).
* What the peer holds is `Announced`: the set of prefixes for a
best-route session, as before; or for an all-paths session, for each
prefix the routes announced, keyed by the peer they came from and that
peer's own identifier, with the identifier they went out with and the
form they went out in. A route keeps its identifier for as long as it
is announced, goes out again only if it changed, and is withdrawn by
its identifier; a new route gets the lowest identifier not in use for
the prefix, from 1.
* Verdicts carry either kind (`Verdict::Best`, `Verdict::All`), and a
reset of the table puts what was announced in doubt until heard of
again, as before, with the same identifiers kept across the reset.
* The record for an all-paths session is about 50 bytes a route, some
tens of megabytes for a full table from several neighbors; the
best-route bookkeeping is unchanged in size.
Also, so that a collector session can be watched: the number of routes
advertised to each peer and not withdrawn since, every route counted
where several are sent for a prefix. The exporter keeps it in the
session's counters after every change; it is `advertised_routes` in
`/api/peers`, the "sent" column of the status page's neighbor table,
and the gauge `bgp_peer_advertised_routes{peer}`.
Documentation: a "Feeding a Route Collector" section in the guide to
passing routes on, with the configuration for a collector; `all_paths`
in the configuration reference; the ADD-PATH sections of the neighbor
guide and the standards reference; the limitation that was removed;
the new field, column and metric in the HTTP API, monitoring and
metrics references.
Testing: an integration test with two feeders and a collector that
negotiated ADD-PATH receive, which checks the two routes with their
identifiers, the withdrawal of one by its identifier, a changed route
keeping its identifier and a new route taking the free one; a
configuration test for `all_paths` without `learned_routes`; a new
`collector` phase of the interoperability lab in which FRR, as a route
collector, is told both of BIRD's routes for a prefix from BIRD's two
sessions and holds them apart, and loses one when its session is
disabled, with the advertised count checked at each step. The workspace tests, the kernel tests and every lab phase pass.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
23 KiB
+++ title = "Configuration Reference" description = "Describes every statement of the Ferrix configuration file, with its type, default value, and range." weight = 1
[extra] nav = "Configuration" +++
Ferrix reads its configuration from a single file at startup. The file
contains a BgpConfig Protocol Buffers message in text format. The schema
is defined in
crates/server/proto/config.proto.
A test in the source tree verifies that this topic describes every field of
the schema.
File Format
The following example shows the elements of the text format:
# A comment.
router_id: "192.0.2.1" # string
local_asn: 64500 # number
collision_detect_established_state: true # boolean
peers { # message
name: "a"
role: PEER # enumeration value
address_families: IPV4_UNICAST # repeated field: one line per value
address_families: IPV6_UNICAST
}
peers { name: "b" } # repeated message
Statements can appear in any order. An omitted statement has its default
value. Ferrix rejects a file that contains an unknown statement or a value
that cannot be parsed. To validate a file, use bgp --check.
BgpConfig
Top-level statements.
| Statement | Default | Description |
|---|---|---|
router_id string |
Required | Specifies the BGP identifier as a dotted-quad IPv4 address other than 0.0.0.0. Required on IPv6-only routers (RFC 4271). |
local_asn uint32 |
Required | Specifies the local AS number. Four-octet AS numbers are supported (RFC 6793). Range: 1 through 4,294,967,295. |
listen_endpoints TcpEndpoint, repeated |
0.0.0.0:179, [::]:179 |
Specifies the addresses and ports on which Ferrix accepts BGP connections. |
peers Peer, repeated |
None | Specifies the BGP neighbors. |
originate OriginatedRoute, repeated |
None | Specifies the routes that Ferrix originates and advertises to every neighbor. |
http_endpoint TcpEndpoint |
Disabled | Specifies the address and port of the status page, HTTP API, and metrics. The port is required. The interface is not authenticated. |
connect_retry_seconds uint32 |
5 | Specifies the initial interval between connection attempts to a neighbor, in seconds. The interval doubles after each failure, up to 120 seconds. |
collision_detect_established_state bool |
false |
Enables connection collision detection for sessions in the Established state (RFC 4271 Section 8.1.1). When disabled, Ferrix closes a new connection from a neighbor that has an established session. |
accept_unconfigured_peers bool |
false |
Accepts sessions from any address, with any AS number. Use only for testing on an isolated network. |
rpki Rpki |
Disabled | Enables RPKI route origin validation and ASPA verification. |
kernel Kernel |
Disabled | Enables kernel route installation (Linux only). |
export ExportPolicy |
Originated routes only | Specifies the export policy for neighbors that have no export statement. |
control_communities bool |
false |
Enables control communities, which restrict the neighbors to which a route is advertised and prepend the local AS number on its way to them. See Control Communities. |
cluster_id string |
router_id |
Specifies the cluster ID that the router uses as a route reflector, as a dotted-quad IPv4 address. See Route Reflection. |
graceful_restart GracefulRestart |
Enabled | Specifies graceful restart for neighbors that have no graceful_restart statement. Its restart_time_seconds also limits how long Ferrix waits at startup for neighbors to send their routes. |
export_limits ExportLimits |
None | Specifies limits on the routes advertised to neighbors whose role is PROVIDER, PEER, or ROUTE_SERVER, and to EBGP neighbors without a role, for neighbors that have no export_limits statement. See Export Limits. |
community_names CommunityName, repeated |
None | Specifies names that the status page displays for communities, in place of the numbers. Ferrix does not use the names otherwise. |
Peer
Statements for a BGP neighbor.
| Statement | Default | Description |
|---|---|---|
name string |
The neighbor's address | Specifies the name of the neighbor in logs, metrics, and the status page. Must be unique. |
endpoint TcpEndpoint |
Required | Specifies the address and port of the neighbor. For a link-local address, include the interface: fe80::1%eth0. Must be unique. |
remote_asn uint32 |
Required | Specifies the AS number of the neighbor. If it equals local_asn, the neighbor is an IBGP neighbor. Range: 1 through 4,294,967,295. |
hold_time_seconds uint32, optional |
90 | Specifies the hold time proposed in the OPEN message, in seconds. Range: 0, or 3 through 65535. A value of 0 disables keepalive messages and the hold timer. |
local_address string |
Selected by the operating system | Specifies the source address for connections to the neighbor, and the next hop of routes advertised to it. Must be of the same address family as endpoint. |
address_families AddressFamily, repeated |
All | Specifies the address families proposed to the neighbor. A family is enabled only if the neighbor also proposes it (RFC 4760). |
add_path AddPath |
ADD_PATH_OFF |
Specifies the ADD-PATH directions proposed to the neighbor (RFC 7911). |
import ImportPolicy |
Default checks | Specifies the import policy for routes received from the neighbor. |
role Role |
None | Specifies the BGP role of the neighbor (RFC 9234). Not permitted for IBGP neighbors. Required for every EBGP neighbor if any export statement enables learned_routes. |
require_role bool |
false |
Rejects the session if the neighbor does not advertise a BGP role. Requires role. |
passive bool |
false |
Prevents Ferrix from initiating connections to the neighbor. Ferrix accepts connections from the address of endpoint; the port of endpoint is not used. See Passive Neighbors. |
expected_routes uint32 |
0 | Specifies the approximate number of routes that the neighbor advertises in normal operation. The status page marks an established session with fewer than half this number of routes as needing attention. Ferrix also allocates the routing table with room for the largest expected_routes value among the neighbors at startup, which avoids the table growing, and briefly using twice its memory, while the tables are received. The value does not affect which routes are accepted. 0 disables the comparison. See Expected Route Counts. |
export ExportPolicy |
Top-level export |
Specifies the export policy for the neighbor. Replaces the top-level export statement. |
graceful_restart GracefulRestart |
Top-level graceful_restart |
Specifies graceful restart for the neighbor. Each statement that is set replaces the corresponding top-level statement. |
route_reflector_client bool |
false |
Makes the IBGP neighbor a route reflector client: Ferrix advertises to it the routes learned from other IBGP neighbors, and advertises its routes to them. Permitted only for IBGP neighbors. See Route Reflection. |
export_limits ExportLimits |
Top-level export_limits |
Specifies limits on the routes advertised to the neighbor. Replaces the top-level export_limits statement. An empty statement removes the limits for the neighbor. Applies only if the neighbor's role is PROVIDER, PEER, or ROUTE_SERVER, or if it is an EBGP neighbor without a role. |
groups uint32, repeated |
None | Specifies the groups of the session, by number, for control communities that name sessions by group. Use the same numbers on all routers in the local AS. Range: 1 through 4,294,967,295. See Session Groups. |
TcpEndpoint
An IP address and TCP port.
| Statement | Default | Description |
|---|---|---|
address string |
Required | Specifies an IPv4 or IPv6 address. A neighbor's link-local IPv6 address requires the interface: fe80::1%eth0. |
port uint32 |
179 | Specifies the TCP port. Required for http_endpoint and RPKI caches. |
ImportPolicy
Statements that determine which routes received from a neighbor are accepted. See Import Policy.
| Statement | Default | Description |
|---|---|---|
max_prefixes uint32 |
0 (no limit) | Specifies the maximum number of routes that the neighbor can have in the routing table. If the limit is exceeded, Ferrix tears down the session and places the neighbor in hold-down. |
hold_down_seconds uint32 |
600 | Specifies the hold-down time, in seconds, after the neighbor exceeds max_prefixes, or after the routes to be advertised to it exceed export_limits.max_prefixes. |
accept_bogons bool |
false |
Accepts bogon prefixes, and AS paths that contain private, reserved, or documentation AS numbers. |
accept_blackholes bool |
false |
Accepts routes with the BLACKHOLE community (RFC 7999) for single addresses, and installs them as blackhole routes. See Blackhole Routes. |
accept_default_route bool |
false |
Accepts the default routes 0.0.0.0/0 and ::/0. |
max_ipv4_prefix_length uint32 |
24 | Specifies the longest IPv4 prefix accepted. |
max_ipv6_prefix_length uint32 |
48 | Specifies the longest IPv6 prefix accepted. |
accept_any_first_as bool |
false |
Accepts AS paths that do not begin with the neighbor's AS number. Required for Internet exchange route servers. |
max_as_path_length uint32 |
64 | Specifies the longest AS path accepted, in AS numbers. |
prefixes PrefixRange, repeated |
All prefixes | Specifies the prefixes that the neighbor can advertise. |
origin_asns uint32, repeated |
All AS numbers | Specifies the AS numbers from which the neighbor's routes can originate. |
accept_rpki_invalid bool |
false |
Accepts routes whose origin is RPKI invalid. |
accept_aspa_invalid bool |
false |
Accepts routes whose AS path is ASPA invalid. |
accept_as_sets bool |
false |
Accepts AS paths that contain an AS_SET (RFC 9774). |
accept_third_party_next_hop bool |
false |
Accepts next hops other than the neighbor's address. Not required for a neighbor with the role ROUTE_SERVER. |
add_communities string, repeated |
None | Specifies standard communities added to accepted routes, for example 64500:100 or NO_EXPORT. |
add_large_communities string, repeated |
None | Specifies large communities added to accepted routes, for example 64500:2:1. |
remove_communities string, repeated |
None | Specifies patterns of communities removed from accepted routes, for example 64500:100, 64500:*, or 64500:2:*. Applied before communities are added. |
local_pref uint32, optional |
100 | Specifies the local preference of accepted routes. |
rules ImportRule, repeated |
None | Specifies rules for some of the accepted routes. Ferrix applies the first rule that matches a route. See Import Rules. |
accept_control_communities bool |
false |
Retains the local AS's communities on routes from an EBGP neighbor, so that the neighbor can set control communities on its own routes. By default, Ferrix removes them. Has no effect for an IBGP neighbor. See Communities of the Local AS. |
ImportRule
A rule for the routes with certain communities or prefixes. A route matches a rule if it matches every condition that the rule specifies. The communities are those of the route after the other statements of the import policy are applied.
| Statement | Default | Description |
|---|---|---|
match_communities string, repeated |
Any route | Specifies patterns of communities. A route matches if it has a community that matches one of them. The patterns are those of remove_communities. |
match_prefixes PrefixRange, repeated |
Any prefix | Specifies prefixes. A route matches if its prefix is permitted by one of them. |
local_pref uint32, optional |
Not changed | Specifies the local preference of matching routes. Replaces the local_pref of the import policy. |
add_communities string, repeated |
None | Specifies standard communities added to matching routes. |
add_large_communities string, repeated |
None | Specifies large communities added to matching routes. |
PrefixRange
A prefix and, optionally, the more specific prefixes within it.
| Statement | Default | Description |
|---|---|---|
prefix string |
Required | Specifies a prefix in CIDR notation, for example 193.0.0.0/21. |
max_length uint32 |
Length of prefix |
Specifies the longest more specific prefix that is also permitted. |
ExportPolicy
Statements that determine which routes are advertised to a neighbor. See Route Advertisement.
| Statement | Default | Description |
|---|---|---|
learned_routes bool |
false |
Enables the advertisement of learned routes, subject to BGP roles and communities. |
all_paths bool |
false |
Advertises every accepted route for a prefix, not only the best path, each with a path identifier (ADD-PATH, RFC 7911). Requires learned_routes, and takes effect for an address family only if the neighbor negotiated ADD-PATH receive for it; otherwise the best path is advertised. Export policy and export limits apply to every route. See Feeding a Route Collector. |
add_communities string, repeated |
None | Specifies standard communities added to advertised routes. |
add_large_communities string, repeated |
None | Specifies large communities added to advertised routes. |
remove_communities string, repeated |
None | Specifies patterns of communities removed from advertised routes. Applied before communities are added. |
as_path_prepend uint32 |
0 | Specifies the number of additional times the local AS number is prepended to the AS path. Range: 0 through 16. |
ExportLimits
Limits on the routes advertised to a neighbor. The limits apply regardless of the export policy, BGP roles, and communities of the routes. See Export Limits.
| Statement | Default | Description |
|---|---|---|
prefixes PrefixRange, repeated |
All prefixes | Specifies the prefixes that can be advertised to the neighbor. Ferrix does not advertise learned or originated routes for other prefixes. |
max_prefixes uint32 |
0 (no limit) | Specifies the maximum number of routes advertised to the neighbor. If more routes are to be advertised, Ferrix advertises none of them, tears down the session with a Cease NOTIFICATION message (subcode Administrative Shutdown) that states the reason (RFC 9003), and places the neighbor in hold-down for its import.hold_down_seconds. |
CommunityName
A name for a community, or for a kind of community, displayed on the status page.
| Statement | Default | Description |
|---|---|---|
community string |
Required | Specifies a standard community (64500:100), a large community (64500:100:2), or a pattern with * for a part left open (64500:102:*). For a pattern, the status page displays the name followed by the open part. |
name string |
Required | Specifies the name to display. |
OriginatedRoute
A route that Ferrix originates.
| Statement | Default | Description |
|---|---|---|
prefix string |
Required | Specifies the prefix in CIDR notation, for example 198.51.100.0/24 or 2001:db8:100::/40. |
origin string |
IGP |
Specifies the ORIGIN attribute: IGP, EGP, or INCOMPLETE. |
as_path_prepend uint32 |
0 | Specifies the number of additional times the local AS number is prepended to the AS path. Range: 0 through 16. |
med uint32, optional |
None | Specifies the MULTI_EXIT_DISC attribute. If not set, the attribute is not sent. |
communities string, repeated |
None | Specifies standard communities (RFC 1997), for example 64500:100 or NO_EXPORT. |
large_communities string, repeated |
None | Specifies large communities (RFC 8092), for example 64500:2:1. |
Rpki
Statements for RPKI validation. See RPKI Origin Validation and ASPA.
| Statement | Default | Description |
|---|---|---|
caches TcpEndpoint, repeated |
Required | Specifies the RTR servers of RPKI caches, in order of preference. The port is required. |
refresh_seconds uint32 |
Cache value, or 3600 | Specifies the interval at which Ferrix requests updates, in seconds. |
retry_seconds uint32 |
Cache value, or 600 | Specifies the interval after which Ferrix retries a failed request, in seconds. |
expire_seconds uint32 |
Cache value, or 7200 | Specifies the time after which Ferrix discards data that no cache has confirmed, in seconds. |
Kernel
Statements for kernel route installation. See Kernel Route Installation.
| Statement | Default | Description |
|---|---|---|
table uint32 |
254 (main) |
Specifies the kernel routing table. |
metric uint32, optional |
20 | Specifies the metric of installed routes. |
without_nexthop_objects bool |
false |
Installs each route with its own gateway instead of a nexthop object. |
stale_seconds uint32, optional |
120 | Specifies the time, in seconds, for which routes installed by a previous run are retained at startup. A value of 0 removes them immediately. |
resolution_table uint32 |
254 (main) |
Specifies the kernel routing table whose routes resolve next hops that are not directly connected. Routes with protocol bgp in this table are not used. See Next Hop Resolution. |
resolve_via_default_route bool |
false |
Permits the default route of the resolution table to resolve a next hop. |
GracefulRestart
Statements for graceful restart (RFC 4724, RFC 8538). See Graceful Restart.
| Statement | Default | Description |
|---|---|---|
disabled bool, optional |
false |
Disables graceful restart. Ferrix does not advertise the capability, and removes the routes of a neighbor as soon as its session ends. |
restart_time_seconds uint32, optional |
120 | Specifies the restart time advertised to neighbors, in seconds: the time for which a neighbor retains the routes of Ferrix after the session ends. Range: 0 through 4095. |
stale_routes_seconds uint32, optional |
120 | Specifies the maximum time, in seconds, for which Ferrix retains the routes of a restarting neighbor: while the neighbor is down, regardless of the restart time that it advertises, and again after it reconnects, until it has sent all its routes. A value of 0 retains no routes. |
Role
| Value | Description |
|---|---|
PROVIDER |
The neighbor provides transit to the local AS. |
CUSTOMER |
The neighbor receives transit from the local AS. |
PEER |
The neighbor exchanges its own and its customers' routes with the local AS. |
ROUTE_SERVER |
The neighbor is an Internet exchange route server. |
ROUTE_SERVER_CLIENT |
The neighbor is a client of a route server operated by the local AS. |
AddressFamily
| Value | Description |
|---|---|
IPV4_UNICAST |
IPv4 unicast (AFI 1, SAFI 1) |
IPV6_UNICAST |
IPv6 unicast (AFI 2, SAFI 1) |
AddPath
| Value | Description |
|---|---|
ADD_PATH_OFF |
ADD-PATH is disabled. |
ADD_PATH_RECEIVE |
Ferrix accepts multiple paths for each prefix from the neighbor. |
ADD_PATH_SEND |
Ferrix proposes to send multiple paths. Ferrix currently sends one path for each prefix. |
ADD_PATH_BOTH |
Both ADD_PATH_RECEIVE and ADD_PATH_SEND. |