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.