bird_exporter: Inconsistent state label for BIRD 2 BGP protocol with multiple AF channels
Mikhail Mayorov
mm at tagan.ru
Mon Jun 1 15:22:16 CEST 2026
Hello.
This is not directly related to BIRD itself. BIRD appears to work
correctly in this case. The question is about how |bird_exporter|exposes
metrics for a BIRD 2 BGP protocol with multiple address-family channels.
I am using |bird_exporter| with BIRD 2 and noticed confusing behavior
when a single BGP protocol has more than one address-family channel
enabled, for example both |ipv4| and |ipv6|.
Versions:
|bird_exporter: 1.5.0 BIRD: 2.19.0 |
Exporter is started like this:
|bird_exporter \ -web.listen-address=localhost:9325 \ -bird.v2 \
-bird.socket=/path/to/bird.ctl |
BIRD shows one established BGP session with both IPv4 and IPv6 channels up:
|Name Proto State Info example_peer BGP up Established BGP state:
Established Neighbor address: 2001:db8::1 Source address: 2001:db8::2
Local capabilities: Multiprotocol AF announced: ipv4 ipv6 Neighbor
capabilities: Multiprotocol AF announced: ipv4 ipv6 Channel ipv4 State:
UP Table: master4 Routes: 10 imported, 0 filtered, 6000 exported, 10
preferred Channel ipv6 State: UP Table: master6 Routes: 0 imported, 0
filtered, 200 exported, 0 preferred |
Actual |bird_exporter| output:
|bird_protocol_up{export_filter="(unnamed)",import_filter="(unnamed)",ip_version="4",name="example_peer",proto="BGP",state="Established"}
1
bird_protocol_up{export_filter="(unnamed)",import_filter="(unnamed)",ip_version="6",name="example_peer",proto="BGP",state=""}
1
bird_protocol_uptime{export_filter="(unnamed)",import_filter="(unnamed)",ip_version="4",name="example_peer",proto="BGP"}
397
bird_protocol_uptime{export_filter="(unnamed)",import_filter="(unnamed)",ip_version="6",name="example_peer",proto="BGP"}
397
bird_protocol_prefix_export_count{export_filter="(unnamed)",import_filter="(unnamed)",ip_version="4",name="example_peer",proto="BGP"}
6000
bird_protocol_prefix_export_count{export_filter="(unnamed)",import_filter="(unnamed)",ip_version="6",name="example_peer",proto="BGP"}
200
bird_protocol_prefix_import_count{export_filter="(unnamed)",import_filter="(unnamed)",ip_version="4",name="example_peer",proto="BGP"}
10
bird_protocol_prefix_import_count{export_filter="(unnamed)",import_filter="(unnamed)",ip_version="6",name="example_peer",proto="BGP"}
0
bird_protocol_prefix_preferred_count{export_filter="(unnamed)",import_filter="(unnamed)",ip_version="4",name="example_peer",proto="BGP"}
10
bird_protocol_prefix_preferred_count{export_filter="(unnamed)",import_filter="(unnamed)",ip_version="6",name="example_peer",proto="BGP"}
0 |
The important part is that both |ip_version="4"| and |ip_version="6"|
are exported for the same BGP protocol, but only one series has the BGP
FSM state:
|bird_protocol_up{ip_version="4",name="example_peer",proto="BGP",state="Established"}
1
bird_protocol_up{ip_version="6",name="example_peer",proto="BGP",state=""} 1 |
The IPv6 series has |state=""|, although the BGP protocol is established
and the IPv6 channel is UP.
Expected behavior:
Either |state="Established"| should be present on all |bird_protocol_up|
series generated from the same established BGP protocol:
|bird_protocol_up{ip_version="4",name="example_peer",proto="BGP",state="Established"}
1
bird_protocol_up{ip_version="6",name="example_peer",proto="BGP",state="Established"}
1 |
or |state| should not be attached to per-AF |bird_protocol_up| series at
all, and a separate protocol-level metric should expose the BGP FSM state.
The current behavior is confusing for monitoring systems, because the
same BGP protocol appears as partly established and partly without
state, although both address-family channels are UP.
It would also be useful to distinguish clearly between:
*
protocol/session state, for example |BGP state: Established|;
*
channel state, for example |Channel ipv4: UP|, |Channel ipv6: UP|;
*
address-family label, currently exposed as |ip_version|.
A cleaner model could be something like:
|bird_protocol_up{name="example_peer",proto="BGP",state="Established"} 1
bird_protocol_channel_up{name="example_peer",proto="BGP",channel="ipv4"}
1
bird_protocol_channel_up{name="example_peer",proto="BGP",channel="ipv6"} 1 |
This would avoid ambiguity when one BIRD 2 protocol serves multiple
address families.
Thank you.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://trubka.network.cz/pipermail/bird-users/attachments/20260601/1418df3f/attachment.htm>
More information about the Bird-users
mailing list