diff options
Diffstat (limited to 'bgpd/bgp_ecommunity.c')
-rw-r--r-- | bgpd/bgp_ecommunity.c | 66 |
1 files changed, 65 insertions, 1 deletions
diff --git a/bgpd/bgp_ecommunity.c b/bgpd/bgp_ecommunity.c index 8b60ead38..54ec7d392 100644 --- a/bgpd/bgp_ecommunity.c +++ b/bgpd/bgp_ecommunity.c @@ -33,6 +33,13 @@ #include "bgpd/bgp_ecommunity.h" #include "bgpd/bgp_lcommunity.h" #include "bgpd/bgp_aspath.h" +#include "bgpd/bgp_flowspec_private.h" + +/* struct used to dump the rate contained in FS set traffic-rate EC */ +union traffic_rate { + float rate_float; + uint8_t rate_byte[4]; +}; /* Hash of community attribute. */ static struct hash *ecomhash; @@ -661,8 +668,10 @@ char *ecommunity_ecom2str(struct ecommunity *ecom, int format, int filter) } /* Space between each value. */ - if (!first) + if (!first) { str_buf[str_pnt++] = ' '; + len++; + } pnt = ecom->val + (i * 8); @@ -727,6 +736,61 @@ char *ecommunity_ecom2str(struct ecommunity *ecom, int format, int filter) "MM:%u", seqnum); } else unk_ecom = 1; + } else if (type == ECOMMUNITY_ENCODE_TRANS_EXP) { + sub_type = *pnt++; + + if (sub_type == ECOMMUNITY_TRAFFIC_ACTION) { + char action[64]; + char *ptr = action; + + if (*(pnt+3) == + 1 << FLOWSPEC_TRAFFIC_ACTION_TERMINAL) + ptr += snprintf(ptr, sizeof(action), + "terminate (apply)"); + else + ptr += snprintf(ptr, sizeof(action), + "eval stops"); + if (*(pnt+3) == + 1 << FLOWSPEC_TRAFFIC_ACTION_SAMPLE) + snprintf(ptr, sizeof(action) - + (size_t)(ptr-action), + ", sample"); + len = snprintf(str_buf + str_pnt, + str_size - len, + "FS:action %s", action); + } else if (sub_type == ECOMMUNITY_TRAFFIC_RATE) { + union traffic_rate data; + + data.rate_byte[3] = *(pnt+2); + data.rate_byte[2] = *(pnt+3); + data.rate_byte[1] = *(pnt+4); + data.rate_byte[0] = *(pnt+5); + len = sprintf( + str_buf + str_pnt, + "FS:rate %f", data.rate_float); + } else if (sub_type == ECOMMUNITY_REDIRECT_VRF) { + char buf[16]; + + memset(buf, 0, sizeof(buf)); + ecommunity_rt_soo_str(buf, (uint8_t *)pnt, + type & + ~ECOMMUNITY_ENCODE_TRANS_EXP, + ECOMMUNITY_ROUTE_TARGET, + ECOMMUNITY_FORMAT_DISPLAY); + len = snprintf( + str_buf + str_pnt, + str_size - len, + "FS:redirect VRF %s", buf); + } else if (sub_type == ECOMMUNITY_TRAFFIC_MARKING) { + len = sprintf( + str_buf + str_pnt, + "FS:marking %u", *(pnt+5)); + } else if (sub_type == ECOMMUNITY_REDIRECT_IP_NH) { + len = sprintf( + str_buf + str_pnt, + "FS:redirect IP 0x%x", *(pnt+5)); + } else + unk_ecom = 1; } else unk_ecom = 1; |