Skip to content

Commit

Permalink
bgpd: skip bmp messages when vrf id is unknown
Browse files Browse the repository at this point in the history
changed result type of bmp_get_peer_distinguisher to int
added result pointer parameter to bmp_get_peer_distinguisher
bmp_get_peer_distinguisher returns 0 means the result is valid else
  error occured do not use result

Signed-off-by: Maxence Younsi <[email protected]>
  • Loading branch information
mxyns committed Sep 13, 2023
1 parent 89261d3 commit 50db848
Showing 1 changed file with 48 additions and 32 deletions.
80 changes: 48 additions & 32 deletions bgpd/bgp_bmp.c
Original file line number Diff line number Diff line change
Expand Up @@ -245,45 +245,41 @@ static void bmp_free(struct bmp *bmp)
#define BMP_PEER_TYPE_LOCAL_INSTANCE 2
#define BMP_PEER_TYPE_LOC_RIB_INSTANCE 3

static inline uint64_t bmp_get_peer_distinguisher(struct bmp *bmp, afi_t afi,
uint8_t peer_type)
static inline int bmp_get_peer_distinguisher(struct bmp *bmp, afi_t afi,
uint8_t peer_type,
uint64_t *result_ref)
{

/* remove this check when the other peer types get correct peer dist.
*(RFC7854) impl.
* for now, always return no error and 0 peer distinguisher as before
*/
if (peer_type != BMP_PEER_TYPE_LOC_RIB_INSTANCE)
return 0;
return (*result_ref = 0);

/* sending vrf_id or rd could be turned into an option at some point */
struct bgp *bgp = bmp->targets->bgp;

/* default vrf => can't have RD => 0
* vrf => has RD?
* if yes => use RD value
* else => use vrf_id
* vrf_id == VRF_UNKNOWN ?
* if yes => 0
* else => convert it so that
* peer_distinguisher is 0::vrf_id
*/
/* vrf default => ok, distinguisher 0 */
if (bgp->inst_type == VRF_DEFAULT)
return 0;
return (*result_ref = 0);

/* use RD if set in VRF config for this AFI */
struct prefix_rd *prd = &bgp->vpn_policy[afi].tovpn_rd;

if (CHECK_FLAG(bgp->vpn_policy[afi].flags,
BGP_VPN_POLICY_TOVPN_RD_SET)) {
uint64_t peerd = 0;

memcpy(&peerd, prd->val, sizeof(prd->val));
return peerd;
memcpy(result_ref, prd->val, sizeof(prd->val));
return 0;
}

/* VRF has no id => error => message should be skipped */
if (bgp->vrf_id == VRF_UNKNOWN)
return 0;
return 1;

return ((uint64_t)htonl(bgp->vrf_id)) << 32;
/* use VRF id converted to ::vrf_id 64bits format */
*result_ref = ((uint64_t)htonl(bgp->vrf_id)) << 32;
return 0;
}

static void bmp_common_hdr(struct stream *s, uint8_t ver, uint8_t type)
Expand Down Expand Up @@ -391,8 +387,8 @@ bmp_put_vrftablename_info_tlv(struct stream *s, struct bmp *bmp)
static int bmp_send_initiation(struct bmp *bmp)
{
int len;
struct stream *s;
s = stream_new(BGP_MAX_PACKET_SIZE);
struct stream *s = stream_new(BGP_MAX_PACKET_SIZE);

bmp_common_hdr(s, BMP_VERSION_3, BMP_TYPE_INITIATION);

#define BMP_INFO_TYPE_SYSDESCR 1
Expand Down Expand Up @@ -884,15 +880,22 @@ static void bmp_eor(struct bmp *bmp, afi_t afi, safi_t safi, uint8_t flags,
if (!peer->afc_nego[afi][safi])
continue;

uint64_t peer_distinguisher = 0;
/* skip this message if peer distinguisher is not available */
if (bmp_get_peer_distinguisher(bmp, afi, peer_type_flag,
&peer_distinguisher)) {
zlog_debug(
"skipping bmp message for reason: can't get peer distinguisher");
continue;
}

s2 = stream_new(BGP_MAX_PACKET_SIZE);

bmp_common_hdr(s2, BMP_VERSION_3,
BMP_TYPE_ROUTE_MONITORING);

bmp_per_peer_hdr(
s2, bmp->targets->bgp, peer, flags, peer_type_flag,
bmp_get_peer_distinguisher(bmp, afi, peer_type_flag),
NULL);
bmp_per_peer_hdr(s2, bmp->targets->bgp, peer, flags,
peer_type_flag, peer_distinguisher, NULL);

stream_putl_at(s2, BMP_LENGTH_POS,
stream_get_endp(s) + stream_get_endp(s2));
Expand Down Expand Up @@ -1005,6 +1008,15 @@ static void bmp_monitor(struct bmp *bmp, struct peer *peer, uint8_t flags,
struct timeval tv = { .tv_sec = uptime, .tv_usec = 0 };
struct timeval uptime_real;

uint64_t peer_distinguisher = 0;
/* skip this message if peer distinguisher is not available */
if (bmp_get_peer_distinguisher(bmp, afi, peer_type_flag,
&peer_distinguisher)) {
zlog_debug(
"skipping bmp message for reason: can't get peer distinguisher");
return;
}

monotime_to_realtime(&tv, &uptime_real);
if (attr)
msg = bmp_update(p, prd, peer, attr, afi, safi);
Expand All @@ -1014,7 +1026,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, bmp->targets->bgp, peer, flags, peer_type_flag,
bmp_get_peer_distinguisher(bmp, afi, peer_type_flag),
peer_distinguisher,
uptime == (time_t)(-1L) ? NULL : &uptime_real);

stream_putl_at(hdr, BMP_LENGTH_POS,
Expand Down Expand Up @@ -1541,8 +1553,9 @@ static int bmp_process(struct bgp *bgp, afi_t afi, safi_t safi,
bmp_process_one(bt, &bt->updhash, &bt->updlist, bgp,
afi, safi, bn, peer);

// if bmp_process_one returns NULL
// we don't have anything to do next
/* if bmp_process_one returns NULL
* we don't have anything to do next
*/
if (!last_item)
continue;

Expand Down Expand Up @@ -2811,8 +2824,10 @@ static int bmp_route_update(struct bgp *bgp, afi_t afi, safi_t safi,
struct bmp *bmp;

frr_each (bmp_targets, &bmpbgp->targets, bt) {
if ((is_locribmon_enabled |=
(bt->afimon[afi][safi] & BMP_MON_LOC_RIB)))
is_locribmon_enabled |=
(bt->afimon[afi][safi] & BMP_MON_LOC_RIB);

if (is_locribmon_enabled)
break;
}

Expand All @@ -2838,8 +2853,9 @@ static int bmp_route_update(struct bgp *bgp, afi_t afi, safi_t safi,
bt, &bt->locupdhash, &bt->locupdlist, bgp, afi,
safi, bn, peer);

// if bmp_process_one returns NULL
// we don't have anything to do next
/* if bmp_process_one returns NULL
* we don't have anything to do next
*/
if (!last_item)
continue;

Expand Down

0 comments on commit 50db848

Please sign in to comment.