diff options
Diffstat (limited to 'bgpd')
-rw-r--r-- | bgpd/bgp_ecommunity.c | 66 | ||||
-rw-r--r-- | bgpd/bgp_ecommunity.h | 9 | ||||
-rw-r--r-- | bgpd/bgp_flowspec_private.h | 5 |
3 files changed, 79 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; diff --git a/bgpd/bgp_ecommunity.h b/bgpd/bgp_ecommunity.h index 028b7a316..31ff1481b 100644 --- a/bgpd/bgp_ecommunity.h +++ b/bgpd/bgp_ecommunity.h @@ -27,10 +27,19 @@ #define ECOMMUNITY_ENCODE_AS4 0x02 #define ECOMMUNITY_ENCODE_OPAQUE 0x03 #define ECOMMUNITY_ENCODE_EVPN 0x06 +#define ECOMMUNITY_ENCODE_TRANS_EXP 0x80 /* Flow Spec */ +/* RFC7674 */ +#define ECOMMUNITY_EXTENDED_COMMUNITY_PART_2 0x81 +#define ECOMMUNITY_EXTENDED_COMMUNITY_PART_3 0x82 /* Low-order octet of the Extended Communities type field. */ #define ECOMMUNITY_ROUTE_TARGET 0x02 #define ECOMMUNITY_SITE_ORIGIN 0x03 +#define ECOMMUNITY_TRAFFIC_RATE 0x06 /* Flow Spec */ +#define ECOMMUNITY_TRAFFIC_ACTION 0x07 +#define ECOMMUNITY_REDIRECT_VRF 0x08 +#define ECOMMUNITY_TRAFFIC_MARKING 0x09 +#define ECOMMUNITY_REDIRECT_IP_NH 0x00 /* Low-order octet of the Extended Communities type field for EVPN types */ #define ECOMMUNITY_EVPN_SUBTYPE_MACMOBILITY 0x00 diff --git a/bgpd/bgp_flowspec_private.h b/bgpd/bgp_flowspec_private.h index c82bb7851..4f086a9f7 100644 --- a/bgpd/bgp_flowspec_private.h +++ b/bgpd/bgp_flowspec_private.h @@ -21,4 +21,9 @@ #define FLOWSPEC_NLRI_SIZELIMIT 240 +/* Flowspec raffic action bit*/ +#define FLOWSPEC_TRAFFIC_ACTION_TERMINAL 1 +#define FLOWSPEC_TRAFFIC_ACTION_SAMPLE 0 +#define FLOWSPEC_TRAFFIC_ACTION_DISTRIBUTE 1 + #endif /* _FRR_BGP_FLOWSPEC_PRIVATE_H */ |