diff options
| author | mxyns <mx.yns@outlook.fr> | 2022-07-28 16:11:47 +0200 | 
|---|---|---|
| committer | Maxence Younsi <mx.yns@outlook.fr> | 2023-11-04 12:17:48 +0100 | 
| commit | f83857832f6083b27ea40fda1bd32a2095fbfc27 (patch) | |
| tree | 12c48da02fd4fbfb4333e4513923df8124dc6b2f /bgpd/bgp_bmp.c | |
| parent | f9af3476db4734e6994b24d67269993e7d659ef2 (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.c | 48 | 
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);  | 
