summaryrefslogtreecommitdiffstats
path: root/bgpd
diff options
context:
space:
mode:
Diffstat (limited to 'bgpd')
-rw-r--r--bgpd/bgp_ecommunity.c66
-rw-r--r--bgpd/bgp_ecommunity.h9
-rw-r--r--bgpd/bgp_flowspec_private.h5
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 */