summaryrefslogtreecommitdiff
path: root/bgpd/bgp_bmp.c
diff options
context:
space:
mode:
authormxyns <mx.yns@outlook.fr>2022-07-28 16:11:47 +0200
committerMaxence Younsi <mx.yns@outlook.fr>2023-11-04 12:17:48 +0100
commitf83857832f6083b27ea40fda1bd32a2095fbfc27 (patch)
tree12c48da02fd4fbfb4333e4513923df8124dc6b2f /bgpd/bgp_bmp.c
parentf9af3476db4734e6994b24d67269993e7d659ef2 (diff)
bgpd: bmp loc-rib RFC9069 compliant monitoring messages
set field peer bgp id to the peer's remote id in every case except loc-rib (RFC9069 case) in which we put the bgp instance's router-id if available or 0-filled if not available set field peer asn to local primary bgp asn in case of loc-rib instance (RFC9069) else it's set to the peer's asn set field peer address to 0 in loc-rib instance (RFC9069 case) and to the peer's address in other cases had to pass struct bgp reference to bmp_per_peer_hdr to access router-id and such, but it's always safely accessed when used Signed-off-by: Maxence Younsi <mx.yns@outlook.fr>
Diffstat (limited to 'bgpd/bgp_bmp.c')
-rw-r--r--bgpd/bgp_bmp.c48
1 files changed, 29 insertions, 19 deletions
diff --git a/bgpd/bgp_bmp.c b/bgpd/bgp_bmp.c
index 2cce7f84f5..e75f08eaff 100644
--- a/bgpd/bgp_bmp.c
+++ b/bgpd/bgp_bmp.c
@@ -243,15 +243,16 @@ static void bmp_free(struct bmp *bmp)
static uint64_t bmp_get_peer_distinguisher(struct bmp *bmp, afi_t afi)
{
- // legacy : TODO should be turned into an option at some point
- // return bmp->targets->bgp->vrf_id;
+ /* legacy : TODO should be turned into an option at some point
+ * return bmp->targets->bgp->vrf_id;
+ */
struct bgp *bgp = bmp->targets->bgp;
struct prefix_rd *prd = &bgp->vpn_policy[afi].tovpn_rd;
/*
* default vrf => can't have RD => 0
* vrf => has RD?
- * if yes => use RD value
- * else => use vrf_id and convert it so that
+ * if yes => use RD value
+ * else => use vrf_id and convert it so that
* peer_distinguisher is 0::vrf_id
*/
return bgp->inst_type == VRF_DEFAULT ? 0
@@ -266,7 +267,7 @@ static void bmp_common_hdr(struct stream *s, uint8_t ver, uint8_t type)
stream_putc(s, type);
}
-static void bmp_per_peer_hdr(struct stream *s, struct peer *peer, uint8_t flags,
+static void bmp_per_peer_hdr(struct stream *s, struct bgp* bgp, struct peer *peer, uint8_t flags,
uint8_t peer_type_flag,
uint64_t peer_distinguisher,
const struct timeval *tv)
@@ -281,6 +282,8 @@ static void bmp_per_peer_hdr(struct stream *s, struct peer *peer, uint8_t flags,
#define BMP_PEER_FLAG_L (1 << 6)
#define BMP_PEER_FLAG_A (1 << 5)
+ bool is_locrib = peer_type_flag == BMP_PEER_TYPE_LOC_RIB_INSTANCE;
+
/* Peer Type */
stream_putc(s, peer_type_flag);
@@ -295,25 +298,32 @@ static void bmp_per_peer_hdr(struct stream *s, struct peer *peer, uint8_t flags,
stream_put(s, (uint8_t *)&peer_distinguisher, 8);
/* Peer Address */
- if (peer->connection->su.sa.sa_family == AF_INET6)
- stream_put(s, &peer->connection->su.sin6.sin6_addr, 16);
- else if (peer->connection->su.sa.sa_family == AF_INET) {
+ /* Set to 0 if it's a LOC-RIB INSTANCE (RFC 9069) or if it's not an IPv4/6 address */
+ if (is_locrib
+ || (peer->connection->su.sa.sa_family != AF_INET6 && peer->connection->su.sa.sa_family != AF_INET)) {
stream_putl(s, 0);
stream_putl(s, 0);
stream_putl(s, 0);
- stream_put_in_addr(s, &peer->connection->su.sin.sin_addr);
- } else {
stream_putl(s, 0);
+ } else if (peer->connection->su.sa.sa_family == AF_INET6)
+ stream_put(s, &peer->connection->su.sin6.sin6_addr, 16);
+ else if (peer->connection->su.sa.sa_family == AF_INET) {
stream_putl(s, 0);
stream_putl(s, 0);
stream_putl(s, 0);
+ stream_put_in_addr(s, &peer->connection->su.sin.sin_addr);
}
/* Peer AS */
- stream_putl(s, peer->as);
+ /* set peer ASN but for LOC-RIB INSTANCE (RFC 9069) put the local bgp ASN if available or 0 */
+ as_t asn = !is_locrib ? peer->as : bgp ? bgp->as : 0L;
+ stream_putl(s, asn);
/* Peer BGP ID */
- stream_put_in_addr(s, &peer->remote_id);
+ /* set router-id but for LOC-RIB INSTANCE (RFC 9069) put the instance router-id if available or 0 */
+ struct in_addr* bgp_id = !is_locrib ? &peer->remote_id : bgp ? &bgp->router_id : NULL;
+ zlog_info("bmp: per peer header is_locrib=%d, peer->remote_id=%pI4, bgp->router_id=%pI4, selected=%pI4", is_locrib, &peer->remote_id, &bgp->router_id, bgp_id);
+ stream_put_in_addr(s, bgp_id);
/* Timestamp */
if (tv) {
@@ -395,7 +405,7 @@ static struct stream *bmp_peerstate(struct peer *peer, bool down)
bmp_common_hdr(s, BMP_VERSION_3,
BMP_TYPE_PEER_UP_NOTIFICATION);
- bmp_per_peer_hdr(s, peer, 0, BMP_PEER_TYPE_GLOBAL_INSTANCE, 0,
+ bmp_per_peer_hdr(s, peer->bgp, peer, 0, BMP_PEER_TYPE_GLOBAL_INSTANCE, 0,
&uptime_real);
/* Local Address (16 bytes) */
@@ -449,7 +459,7 @@ static struct stream *bmp_peerstate(struct peer *peer, bool down)
bmp_common_hdr(s, BMP_VERSION_3,
BMP_TYPE_PEER_DOWN_NOTIFICATION);
- bmp_per_peer_hdr(s, peer, 0, BMP_PEER_TYPE_GLOBAL_INSTANCE, 0,
+ bmp_per_peer_hdr(s, peer->bgp, peer, 0, BMP_PEER_TYPE_GLOBAL_INSTANCE, 0,
&uptime_real);
type_pos = stream_get_endp(s);
@@ -640,7 +650,7 @@ static void bmp_wrmirror_lost(struct bmp *bmp, struct pullwr *pullwr)
s = stream_new(BGP_MAX_PACKET_SIZE);
bmp_common_hdr(s, BMP_VERSION_3, BMP_TYPE_ROUTE_MIRRORING);
- bmp_per_peer_hdr(s, bmp->targets->bgp->peer_self, 0,
+ bmp_per_peer_hdr(s, bmp->targets->bgp, bmp->targets->bgp->peer_self, 0,
BMP_PEER_TYPE_GLOBAL_INSTANCE, 0, &tv);
stream_putw(s, BMP_MIRROR_TLV_TYPE_INFO);
@@ -679,7 +689,7 @@ static bool bmp_wrmirror(struct bmp *bmp, struct pullwr *pullwr)
s = stream_new(BGP_MAX_PACKET_SIZE);
bmp_common_hdr(s, BMP_VERSION_3, BMP_TYPE_ROUTE_MIRRORING);
- bmp_per_peer_hdr(s, peer, 0, BMP_PEER_TYPE_GLOBAL_INSTANCE, 0,
+ bmp_per_peer_hdr(s, bmp->targets->bgp, peer, 0, BMP_PEER_TYPE_GLOBAL_INSTANCE, 0,
&bmq->tv);
/* BMP Mirror TLV. */
@@ -831,7 +841,7 @@ static void bmp_eor(struct bmp *bmp, afi_t afi, safi_t safi, uint8_t flags, uint
bmp_common_hdr(s2, BMP_VERSION_3,
BMP_TYPE_ROUTE_MONITORING);
- bmp_per_peer_hdr(s2, peer, flags, peer_type_flag, 0, NULL);
+ bmp_per_peer_hdr(s2, bmp->targets->bgp, peer, flags, peer_type_flag, 0, NULL);
stream_putl_at(s2, BMP_LENGTH_POS,
stream_get_endp(s) + stream_get_endp(s2));
@@ -954,7 +964,7 @@ static void bmp_monitor(struct bmp *bmp, struct peer *peer, uint8_t flags,
hdr = stream_new(BGP_MAX_PACKET_SIZE);
bmp_common_hdr(hdr, BMP_VERSION_3, BMP_TYPE_ROUTE_MONITORING);
- bmp_per_peer_hdr(hdr, peer, flags, peer_type_flags, peer_distinguisher_flag, &uptime_real);
+ bmp_per_peer_hdr(hdr, bmp->targets->bgp, peer, flags, peer_type_flags, peer_distinguisher_flag, &uptime_real);
stream_putl_at(hdr, BMP_LENGTH_POS,
stream_get_endp(hdr) + stream_get_endp(msg));
@@ -1535,7 +1545,7 @@ static void bmp_stats(struct event *thread)
s = stream_new(BGP_MAX_PACKET_SIZE);
bmp_common_hdr(s, BMP_VERSION_3, BMP_TYPE_STATISTICS_REPORT);
- bmp_per_peer_hdr(s, peer, 0, BMP_PEER_TYPE_GLOBAL_INSTANCE, 0,
+ bmp_per_peer_hdr(s, bt->bgp, peer, 0, BMP_PEER_TYPE_GLOBAL_INSTANCE, 0,
&tv);
count_pos = stream_get_endp(s);