diff options
Diffstat (limited to 'bgpd/bgp_ecommunity.c')
| -rw-r--r-- | bgpd/bgp_ecommunity.c | 51 |
1 files changed, 31 insertions, 20 deletions
diff --git a/bgpd/bgp_ecommunity.c b/bgpd/bgp_ecommunity.c index 6d3abbd20d..1e95d401aa 100644 --- a/bgpd/bgp_ecommunity.c +++ b/bgpd/bgp_ecommunity.c @@ -201,6 +201,7 @@ ecommunity_uniq_sort_internal(struct ecommunity *ecom, new = ecommunity_new(); new->unit_size = ecom_size; + new->disable_ieee_floating = ecom->disable_ieee_floating; for (i = 0; i < ecom->size; i++) { eval = (void *)(ecom->val + (i * ecom_size)); @@ -220,8 +221,9 @@ struct ecommunity *ecommunity_uniq_sort(struct ecommunity *ecom) /* Parse Extended Communites Attribute in BGP packet. */ static struct ecommunity *ecommunity_parse_internal(uint8_t *pnt, - unsigned short length, - unsigned short size_ecom) + unsigned short length, + unsigned short size_ecom, + bool disable_ieee_floating) { struct ecommunity tmp; struct ecommunity *new; @@ -234,6 +236,7 @@ static struct ecommunity *ecommunity_parse_internal(uint8_t *pnt, Attribute. */ tmp.size = length / size_ecom; tmp.val = pnt; + tmp.disable_ieee_floating = disable_ieee_floating; /* Create a new Extended Communities Attribute by uniq and sort each Extended Communities value */ @@ -242,17 +245,18 @@ static struct ecommunity *ecommunity_parse_internal(uint8_t *pnt, return ecommunity_intern(new); } -struct ecommunity *ecommunity_parse(uint8_t *pnt, - unsigned short length) +struct ecommunity *ecommunity_parse(uint8_t *pnt, unsigned short length, + bool disable_ieee_floating) { - return ecommunity_parse_internal(pnt, length, ECOMMUNITY_SIZE); + return ecommunity_parse_internal(pnt, length, ECOMMUNITY_SIZE, + disable_ieee_floating); } -struct ecommunity *ecommunity_parse_ipv6(uint8_t *pnt, - unsigned short length) +struct ecommunity *ecommunity_parse_ipv6(uint8_t *pnt, unsigned short length, + bool disable_ieee_floating) { - return ecommunity_parse_internal(pnt, length, - IPV6_ECOMMUNITY_SIZE); + return ecommunity_parse_internal(pnt, length, IPV6_ECOMMUNITY_SIZE, + disable_ieee_floating); } /* Duplicate the Extended Communities Attribute structure. */ @@ -847,7 +851,8 @@ static uint32_t ieee_float_uint32_to_uint32(uint32_t u) return (uint32_t)f.r; } -static int ecommunity_lb_str(char *buf, size_t bufsz, const uint8_t *pnt) +static int ecommunity_lb_str(char *buf, size_t bufsz, const uint8_t *pnt, + bool disable_ieee_floating) { int len = 0; as_t as; @@ -862,7 +867,8 @@ static int ecommunity_lb_str(char *buf, size_t bufsz, const uint8_t *pnt) as |= (*pnt++); (void)ptr_get_be32(pnt, &bw_tmp); - bw = ieee_float_uint32_to_uint32(bw_tmp); + bw = disable_ieee_floating ? bw_tmp + : ieee_float_uint32_to_uint32(bw_tmp); if (bw >= ONE_GBPS_BYTES) snprintf(bps_buf, sizeof(bps_buf), "%.3f Gbps", @@ -954,8 +960,9 @@ char *ecommunity_ecom2str(struct ecommunity *ecom, int format, int filter) } else if (sub_type == ECOMMUNITY_LINK_BANDWIDTH && type == ECOMMUNITY_ENCODE_AS) { - ecommunity_lb_str(encbuf, - sizeof(encbuf), pnt); + ecommunity_lb_str( + encbuf, sizeof(encbuf), pnt, + ecom->disable_ieee_floating); } else unk_ecom = 1; } else { @@ -1161,7 +1168,8 @@ char *ecommunity_ecom2str(struct ecommunity *ecom, int format, int filter) } else if (type == ECOMMUNITY_ENCODE_AS_NON_TRANS) { sub_type = *pnt++; if (sub_type == ECOMMUNITY_LINK_BANDWIDTH) - ecommunity_lb_str(encbuf, sizeof(encbuf), pnt); + ecommunity_lb_str(encbuf, sizeof(encbuf), pnt, + ecom->disable_ieee_floating); else unk_ecom = 1; } else { @@ -1547,7 +1555,10 @@ const uint8_t *ecommunity_linkbw_present(struct ecommunity *ecom, uint32_t *bw) pnt = ptr_get_be32(pnt, &bwval); (void)pnt; /* consume value */ if (bw) - *bw = ieee_float_uint32_to_uint32(bwval); + *bw = ecom->disable_ieee_floating + ? bwval + : ieee_float_uint32_to_uint32( + bwval); return eval; } } @@ -1556,9 +1567,9 @@ const uint8_t *ecommunity_linkbw_present(struct ecommunity *ecom, uint32_t *bw) } -struct ecommunity *ecommunity_replace_linkbw(as_t as, - struct ecommunity *ecom, - uint64_t cum_bw) +struct ecommunity *ecommunity_replace_linkbw(as_t as, struct ecommunity *ecom, + uint64_t cum_bw, + bool disable_ieee_floating) { struct ecommunity *new; struct ecommunity_val lb_eval; @@ -1588,8 +1599,8 @@ struct ecommunity *ecommunity_replace_linkbw(as_t as, */ if (cum_bw > 0xFFFFFFFF) cum_bw = 0xFFFFFFFF; - encode_lb_extcomm(as > BGP_AS_MAX ? BGP_AS_TRANS : as, cum_bw, - false, &lb_eval); + encode_lb_extcomm(as > BGP_AS_MAX ? BGP_AS_TRANS : as, cum_bw, false, + &lb_eval, disable_ieee_floating); new = ecommunity_dup(ecom); ecommunity_add_val(new, &lb_eval, true, true); |
