From d901dc13cb566fb3b76c5b6a9427d9c699494c49 Mon Sep 17 00:00:00 2001 From: vivek Date: Tue, 24 Mar 2020 12:17:19 -0700 Subject: [PATCH] bgpd: Check and extract link bandwidth value Extract link bandwidth value into attribute from the extended community, if present. Signed-off-by: Vivek Venkatraman --- bgpd/bgp_attr.c | 3 +++ bgpd/bgp_attr.h | 4 +++- bgpd/bgp_ecommunity.c | 39 +++++++++++++++++++++++++++++++++++++++ bgpd/bgp_ecommunity.h | 3 ++- 4 files changed, 47 insertions(+), 2 deletions(-) diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index 221386e38d..d6eb6beddb 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -2246,6 +2246,9 @@ bgp_attr_ext_communities(struct bgp_attr_parser_args *args) bgp_attr_extcom_tunnel_type(attr, (bgp_encap_types *)&attr->encap_tunneltype); + /* Extract link bandwidth, if any. */ + (void)ecommunity_linkbw_present(attr->ecommunity, &attr->link_bw); + return BGP_ATTR_PARSE_PROCEED; } diff --git a/bgpd/bgp_attr.h b/bgpd/bgp_attr.h index 98a9a620f7..5fec4be29c 100644 --- a/bgpd/bgp_attr.h +++ b/bgpd/bgp_attr.h @@ -250,6 +250,9 @@ struct attr { /* rmap set table */ uint32_t rmap_table_id; + + /* Link bandwidth value, if any. */ + uint32_t link_bw; }; /* rmap_change_flags definition */ @@ -409,5 +412,4 @@ static inline uint32_t mac_mobility_seqnum(struct attr *attr) { return (attr) ? attr->mm_seqnum : 0; } - #endif /* _QUAGGA_BGP_ATTR_H */ diff --git a/bgpd/bgp_ecommunity.c b/bgpd/bgp_ecommunity.c index 5e5a32d420..dd97a3d213 100644 --- a/bgpd/bgp_ecommunity.c +++ b/bgpd/bgp_ecommunity.c @@ -1203,3 +1203,42 @@ void bgp_remove_ecomm_from_aggregate_hash(struct bgp_aggregate *aggregate, } } } + +/* + * return the BGP link bandwidth extended community, if present; + * the actual bandwidth is returned via param + */ +const uint8_t *ecommunity_linkbw_present(struct ecommunity *ecom, uint32_t *bw) +{ + const uint8_t *eval; + int i; + + if (bw) + *bw = 0; + + if (!ecom || !ecom->size) + return NULL; + + for (i = 0; i < ecom->size; i++) { + const uint8_t *pnt; + uint8_t type, sub_type; + uint32_t bwval; + + eval = pnt = (ecom->val + (i * ECOMMUNITY_SIZE)); + type = *pnt++; + sub_type = *pnt++; + + if ((type == ECOMMUNITY_ENCODE_AS || + type == ECOMMUNITY_ENCODE_AS_NON_TRANS) && + sub_type == ECOMMUNITY_LINK_BANDWIDTH) { + pnt += 2; /* bandwidth is encoded as AS:val */ + pnt = ptr_get_be32(pnt, &bwval); + (void)pnt; /* consume value */ + if (bw) + *bw = bwval; + return eval; + } + } + + return NULL; +} diff --git a/bgpd/bgp_ecommunity.h b/bgpd/bgp_ecommunity.h index b61deba922..3aeafb75ea 100644 --- a/bgpd/bgp_ecommunity.h +++ b/bgpd/bgp_ecommunity.h @@ -236,7 +236,8 @@ extern void bgp_remove_ecomm_from_aggregate_hash( struct bgp_aggregate *aggregate, struct ecommunity *ecommunity); extern void bgp_aggr_ecommunity_remove(void *arg); - +extern const uint8_t *ecommunity_linkbw_present(struct ecommunity *ecom, + uint32_t *bw); static inline void ecommunity_strip_rts(struct ecommunity *ecom) { -- 2.39.5