diff options
| -rw-r--r-- | bgpd/bgp_ecommunity.c | 38 | ||||
| -rw-r--r-- | bgpd/bgp_ecommunity.h | 16 |
2 files changed, 53 insertions, 1 deletions
diff --git a/bgpd/bgp_ecommunity.c b/bgpd/bgp_ecommunity.c index fc66494742..5e5a32d420 100644 --- a/bgpd/bgp_ecommunity.c +++ b/bgpd/bgp_ecommunity.c @@ -611,6 +611,33 @@ static int ecommunity_rt_soo_str(char *buf, size_t bufsz, const uint8_t *pnt, return len; } +static int ecommunity_lb_str(char *buf, size_t bufsz, const uint8_t *pnt) +{ + int len = 0; + as_t as; + uint32_t bw; + char bps_buf[20] = {0}; + +#define ONE_GBPS_BYTES (1000 * 1000 * 1000 / 8) +#define ONE_MBPS_BYTES (1000 * 1000 / 8) +#define ONE_KBPS_BYTES (1000 / 8) + + as = (*pnt++ << 8); + as |= (*pnt++); + pnt = ptr_get_be32(pnt, &bw); + if (bw >= ONE_GBPS_BYTES) + sprintf(bps_buf, "%.3f Gbps", (float)(bw/ONE_GBPS_BYTES)); + else if (bw >= ONE_MBPS_BYTES) + sprintf(bps_buf, "%.3f Mbps", (float)(bw/ONE_MBPS_BYTES)); + else if (bw >= ONE_KBPS_BYTES) + sprintf(bps_buf, "%.3f Kbps", (float)(bw/ONE_KBPS_BYTES)); + else + sprintf(bps_buf, "%u bps", bw * 8); + + len = snprintf(buf, bufsz, "LB:%u:%u (%s)", as, bw, bps_buf); + return len; +} + /* Convert extended community attribute to string. Due to historical reason of industry standard implementation, there @@ -686,6 +713,11 @@ char *ecommunity_ecom2str(struct ecommunity *ecom, int format, int filter) INET_ADDRSTRLEN); snprintf(encbuf, sizeof(encbuf), "NH:%s:%d", ipv4str, pnt[5]); + } else if (sub_type == + ECOMMUNITY_LINK_BANDWIDTH && + type == ECOMMUNITY_ENCODE_AS) { + ecommunity_lb_str(encbuf, + sizeof(encbuf), pnt); } else unk_ecom = 1; } else { @@ -821,6 +853,12 @@ char *ecommunity_ecom2str(struct ecommunity *ecom, int format, int filter) (uint8_t)mac.octet[5]); } else unk_ecom = 1; + } else if (type == ECOMMUNITY_ENCODE_AS_NON_TRANS) { + sub_type = *pnt++; + if (sub_type == ECOMMUNITY_LINK_BANDWIDTH) + ecommunity_lb_str(encbuf, sizeof(encbuf), pnt); + else + unk_ecom = 1; } else { sub_type = *pnt++; unk_ecom = 1; diff --git a/bgpd/bgp_ecommunity.h b/bgpd/bgp_ecommunity.h index d4f75d4a08..b61deba922 100644 --- a/bgpd/bgp_ecommunity.h +++ b/bgpd/bgp_ecommunity.h @@ -24,19 +24,33 @@ #include "bgpd/bgp_route.h" #include "bgpd/bgpd.h" +/* Refer to rfc7153 for the IANA registry definitions. These are + * updated by other standards like rfc7674. + */ /* High-order octet of the Extended Communities type field. */ #define ECOMMUNITY_ENCODE_AS 0x00 #define ECOMMUNITY_ENCODE_IP 0x01 #define ECOMMUNITY_ENCODE_AS4 0x02 #define ECOMMUNITY_ENCODE_OPAQUE 0x03 #define ECOMMUNITY_ENCODE_EVPN 0x06 -#define ECOMMUNITY_ENCODE_TRANS_EXP 0x80 /* Flow Spec */ #define ECOMMUNITY_ENCODE_REDIRECT_IP_NH 0x08 /* Flow Spec */ +/* Generic Transitive Experimental */ +#define ECOMMUNITY_ENCODE_TRANS_EXP 0x80 + /* RFC7674 */ #define ECOMMUNITY_EXTENDED_COMMUNITY_PART_2 0x81 #define ECOMMUNITY_EXTENDED_COMMUNITY_PART_3 0x82 +/* Non-transitive extended community types. */ +#define ECOMMUNITY_ENCODE_AS_NON_TRANS 0x40 +#define ECOMMUNITY_ENCODE_IP_NON_TRANS 0x41 +#define ECOMMUNITY_ENCODE_AS4_NON_TRANS 0x42 +#define ECOMMUNITY_ENCODE_OPAQUE_NON_TRANS 0x43 + /* Low-order octet of the Extended Communities type field. */ +/* Note: This really depends on the high-order octet. This means that + * multiple definitions for the same value are possible. + */ #define ECOMMUNITY_ROUTE_TARGET 0x02 #define ECOMMUNITY_SITE_ORIGIN 0x03 #define ECOMMUNITY_LINK_BANDWIDTH 0x04 |
