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
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 {
(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;
#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