From f9af3476db4734e6994b24d67269993e7d659ef2 Mon Sep 17 00:00:00 2001 From: mxyns Date: Wed, 27 Jul 2022 20:40:13 +0200 Subject: [PATCH] bgpd: bmp set peer distinguisher with RD peer distinguisher set to vrf RD if there is one or to vrf_id if in a vrf set to 0 if in default vrf Signed-off-by: Maxence Younsi --- bgpd/bgp_bmp.c | 87 +++++++++++++++++++++++++++++--------------------- 1 file changed, 50 insertions(+), 37 deletions(-) diff --git a/bgpd/bgp_bmp.c b/bgpd/bgp_bmp.c index 33cf2793f4..2cce7f84f5 100644 --- a/bgpd/bgp_bmp.c +++ b/bgpd/bgp_bmp.c @@ -240,6 +240,25 @@ static void bmp_free(struct bmp *bmp) XFREE(MTYPE_BMP_CONN, 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; + 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 + * peer_distinguisher is 0::vrf_id + */ + return bgp->inst_type == VRF_DEFAULT ? 0 + : prd ? *(uint64_t *)prd->val + : (((uint64_t)htonl(bgp->vrf_id)) << 32); +} + static void bmp_common_hdr(struct stream *s, uint8_t ver, uint8_t type) { stream_putc(s, ver); @@ -247,8 +266,10 @@ 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, uint8_t peer_type_flag, uint8_t *peer_distinguisher, const struct timeval *tv) +static void bmp_per_peer_hdr(struct stream *s, struct peer *peer, uint8_t flags, + uint8_t peer_type_flag, + uint64_t peer_distinguisher, + const struct timeval *tv) { #define BMP_PEER_TYPE_GLOBAL_INSTANCE 0 @@ -271,9 +292,7 @@ static void bmp_per_peer_hdr(struct stream *s, struct peer *peer, stream_putc(s, flags); /* Peer Distinguisher */ - uint8_t empty_peer_distinguisher[8] = {0}; - uint64_t peerd = *(uint64_t*)(peer_distinguisher ? peer_distinguisher : empty_peer_distinguisher); - stream_putq(s, peerd); + stream_put(s, (uint8_t *)&peer_distinguisher, 8); /* Peer Address */ if (peer->connection->su.sa.sa_family == AF_INET6) @@ -376,7 +395,8 @@ 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, NULL, &uptime_real); + bmp_per_peer_hdr(s, peer, 0, BMP_PEER_TYPE_GLOBAL_INSTANCE, 0, + &uptime_real); /* Local Address (16 bytes) */ if (peer->su_local->sa.sa_family == AF_INET6) @@ -429,7 +449,8 @@ 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, NULL, &uptime_real); + bmp_per_peer_hdr(s, peer, 0, BMP_PEER_TYPE_GLOBAL_INSTANCE, 0, + &uptime_real); type_pos = stream_get_endp(s); stream_putc(s, 0); /* placeholder for down reason */ @@ -619,7 +640,8 @@ 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_PEER_TYPE_GLOBAL_INSTANCE, NULL, &tv); + bmp_per_peer_hdr(s, bmp->targets->bgp->peer_self, 0, + BMP_PEER_TYPE_GLOBAL_INSTANCE, 0, &tv); stream_putw(s, BMP_MIRROR_TLV_TYPE_INFO); stream_putw(s, 2); @@ -657,7 +679,8 @@ 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, NULL, &bmq->tv); + bmp_per_peer_hdr(s, peer, 0, BMP_PEER_TYPE_GLOBAL_INSTANCE, 0, + &bmq->tv); /* BMP Mirror TLV. */ stream_putw(s, BMP_MIRROR_TLV_TYPE_BGP_MESSAGE); @@ -808,7 +831,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, NULL, NULL); + bmp_per_peer_hdr(s2, peer, flags, peer_type_flag, 0, NULL); stream_putl_at(s2, BMP_LENGTH_POS, stream_get_endp(s) + stream_get_endp(s2)); @@ -914,7 +937,7 @@ static struct stream *bmp_withdraw(const struct prefix *p, static void bmp_monitor(struct bmp *bmp, struct peer *peer, uint8_t flags, uint8_t peer_type_flags, - uint8_t *peer_distinguisher_flag, + uint64_t peer_distinguisher_flag, const struct prefix *p, struct prefix_rd *prd, struct attr *attr, afi_t afi, safi_t safi, time_t uptime) @@ -1112,29 +1135,22 @@ afibreak: (safi == SAFI_MPLS_VPN)) prd = (struct prefix_rd *)bgp_dest_get_prefix(bmp->syncrdpos); - if (bpi && CHECK_FLAG(bpi->flags, BGP_PATH_SELECTED) - && CHECK_FLAG(bmp->targets->afimon[afi][safi], BMP_MON_LOC_RIB)) { - uint8_t peer_distinguisher[8] = {0}; - if (bmp->targets->bgp->inst_type != VRF_DEFAULT) { - memcpy(peer_distinguisher, - &bmp->targets->bgp->vrf_id, - sizeof(vrf_id_t)); - } - - bmp_monitor(bmp, bpi->peer, 0, - BMP_PEER_TYPE_LOC_RIB_INSTANCE, peer_distinguisher, bn_p, - prd, bpi->attr, afi, safi, bpi->uptime); + if (bpi && CHECK_FLAG(bpi->flags, BGP_PATH_SELECTED) && + CHECK_FLAG(bmp->targets->afimon[afi][safi], BMP_MON_LOC_RIB)) { + bmp_monitor(bmp, bpi->peer, 0, BMP_PEER_TYPE_LOC_RIB_INSTANCE, + bmp_get_peer_distinguisher(bmp, afi), bn_p, prd, + bpi->attr, afi, safi, bpi->uptime); } if (bpi && CHECK_FLAG(bpi->flags, BGP_PATH_VALID) && CHECK_FLAG(bmp->targets->afimon[afi][safi], BMP_MON_POSTPOLICY)) bmp_monitor(bmp, bpi->peer, BMP_PEER_FLAG_L, - BMP_PEER_TYPE_GLOBAL_INSTANCE, NULL, bn_p, - prd, bpi->attr, afi, safi, bpi->uptime); + BMP_PEER_TYPE_GLOBAL_INSTANCE, 0, bn_p, prd, + bpi->attr, afi, safi, bpi->uptime); if (adjin) bmp_monitor(bmp, adjin->peer, 0, BMP_PEER_TYPE_GLOBAL_INSTANCE, - NULL, bn_p, prd, adjin->attr, afi, safi, + 0, bn_p, prd, adjin->attr, afi, safi, adjin->uptime); if (bn) @@ -1277,14 +1293,10 @@ static bool bmp_wrqueue_locrib(struct bmp *bmp, struct pullwr *pullwr) break; } - uint8_t peer_distinguisher[8] = {0}; - if (bmp->targets->bgp->inst_type != VRF_DEFAULT) { - memcpy(peer_distinguisher, &bmp->targets->bgp->vrf_id, sizeof(vrf_id_t)); - } - - bmp_monitor(bmp, peer, 0, BMP_PEER_TYPE_LOC_RIB_INSTANCE, peer_distinguisher, - &bqe->p, prd, bpi ? bpi->attr : NULL, - afi, safi, bpi ? bpi->uptime : monotime(NULL)); + bmp_monitor(bmp, peer, 0, BMP_PEER_TYPE_LOC_RIB_INSTANCE, + bmp_get_peer_distinguisher(bmp, afi), &bqe->p, prd, + bpi ? bpi->attr : NULL, afi, safi, + bpi ? bpi->uptime : monotime(NULL)); written = true; out: @@ -1353,7 +1365,7 @@ static bool bmp_wrqueue(struct bmp *bmp, struct pullwr *pullwr) } bmp_monitor(bmp, peer, BMP_PEER_FLAG_L, - BMP_PEER_TYPE_GLOBAL_INSTANCE, NULL, &bqe->p, prd, + BMP_PEER_TYPE_GLOBAL_INSTANCE, 0, &bqe->p, prd, bpi ? bpi->attr : NULL, afi, safi, bpi ? bpi->uptime : monotime(NULL)); written = true; @@ -1367,7 +1379,7 @@ static bool bmp_wrqueue(struct bmp *bmp, struct pullwr *pullwr) if (adjin->peer == peer) break; } - bmp_monitor(bmp, peer, 0, BMP_PEER_TYPE_GLOBAL_INSTANCE, NULL, + bmp_monitor(bmp, peer, 0, BMP_PEER_TYPE_GLOBAL_INSTANCE, 0, &bqe->p, prd, adjin ? adjin->attr : NULL, afi, safi, adjin ? adjin->uptime : monotime(NULL)); written = true; @@ -1523,7 +1535,8 @@ 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, NULL, &tv); + bmp_per_peer_hdr(s, peer, 0, BMP_PEER_TYPE_GLOBAL_INSTANCE, 0, + &tv); count_pos = stream_get_endp(s); stream_putl(s, 0);