summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bgpd/Makefile.am4
-rw-r--r--bgpd/bgp_attr.c20
-rw-r--r--bgpd/bgp_ecommunity.h2
-rw-r--r--bgpd/bgp_flowspec.c78
-rw-r--r--bgpd/bgp_flowspec.h27
-rw-r--r--bgpd/bgp_flowspec_private.h24
-rw-r--r--bgpd/bgp_memory.c7
-rw-r--r--bgpd/bgp_memory.h8
-rw-r--r--bgpd/bgp_open.c11
-rw-r--r--bgpd/bgp_packet.c7
-rw-r--r--bgpd/bgp_vty.c105
-rw-r--r--bgpd/bgp_vty.h3
-rw-r--r--bgpd/bgpd.c21
-rw-r--r--bgpd/bgpd.h9
-rw-r--r--lib/command.c10
-rw-r--r--lib/command.h2
-rw-r--r--lib/prefix.c2
-rw-r--r--lib/zebra.h7
18 files changed, 332 insertions, 15 deletions
diff --git a/bgpd/Makefile.am b/bgpd/Makefile.am
index 5e08f82774..84b3e0183c 100644
--- a/bgpd/Makefile.am
+++ b/bgpd/Makefile.am
@@ -86,7 +86,7 @@ libbgp_a_SOURCES = \
bgp_nht.c bgp_updgrp.c bgp_updgrp_packet.c bgp_updgrp_adv.c bgp_bfd.c \
bgp_encap_tlv.c $(BGP_VNC_RFAPI_SRC) bgp_attr_evpn.c \
bgp_evpn.c bgp_evpn_vty.c bgp_vpn.c bgp_label.c bgp_rd.c \
- bgp_keepalives.c bgp_io.c
+ bgp_keepalives.c bgp_io.c bgp_flowspec.c
noinst_HEADERS = \
bgp_memory.h \
@@ -99,7 +99,7 @@ noinst_HEADERS = \
bgp_updgrp.h bgp_bfd.h bgp_encap_tlv.h bgp_encap_types.h \
$(BGP_VNC_RFAPI_HD) bgp_attr_evpn.h bgp_evpn.h bgp_evpn_vty.h \
bgp_vpn.h bgp_label.h bgp_rd.h bgp_evpn_private.h bgp_keepalives.h \
- bgp_io.h
+ bgp_io.h bgp_flowspec.h bgp_flowspec_private.h
bgpd_SOURCES = bgp_main.c
bgpd_LDADD = libbgp.a $(BGP_VNC_RFP_LIB) ../lib/libfrr.la @LIBCAP@ @LIBM@
diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c
index 58788a8959..639365588c 100644
--- a/bgpd/bgp_attr.c
+++ b/bgpd/bgp_attr.c
@@ -52,6 +52,7 @@
#endif
#include "bgp_encap_types.h"
#include "bgp_evpn.h"
+#include "bgp_flowspec_private.h"
/* Attribute strings for logging. */
static const struct message attr_str[] = {
@@ -1647,6 +1648,13 @@ int bgp_mp_reach_parse(struct bgp_attr_parser_args *args,
/* Nexthop length check. */
switch (attr->mp_nexthop_len) {
+ case 0:
+ if (safi != SAFI_FLOWSPEC) {
+ zlog_info("%s: (%s) Wrong multiprotocol next hop length: %d",
+ __func__, peer->host, attr->mp_nexthop_len);
+ return BGP_ATTR_PARSE_ERROR_NOTIFYPLS;
+ }
+ break;
case BGP_ATTR_NHLEN_VPNV4:
stream_getl(s); /* RD high */
stream_getl(s); /* RD low */
@@ -2669,6 +2677,8 @@ size_t bgp_packet_mpattr_start(struct stream *s, struct peer *peer, afi_t afi,
stream_putc(s, 4);
stream_put(s, &attr->mp_nexthop_global_in, 4);
break;
+ case SAFI_FLOWSPEC:
+ stream_putc(s, 0); /* no nexthop for flowspec */
default:
break;
}
@@ -2719,6 +2729,8 @@ size_t bgp_packet_mpattr_start(struct stream *s, struct peer *peer, afi_t afi,
stream_put(s, &attr->mp_nexthop_global,
IPV6_MAX_BYTELEN);
break;
+ case SAFI_FLOWSPEC:
+ stream_putc(s, 0); /* no nexthop for flowspec */
default:
break;
}
@@ -2756,6 +2768,14 @@ void bgp_packet_mpattr_prefix(struct stream *s, afi_t afi, safi_t safi,
} else if (safi == SAFI_LABELED_UNICAST) {
/* Prefix write with label. */
stream_put_labeled_prefix(s, p, label);
+ } else if (safi == SAFI_FLOWSPEC) {
+ if (PSIZE (p->prefixlen)+2 < FLOWSPEC_NLRI_SIZELIMIT)
+ stream_putc(s, PSIZE (p->prefixlen)+2);
+ else
+ stream_putw(s, (PSIZE (p->prefixlen)+2)|(0xf<<12));
+ stream_putc(s, 2);/* Filter type */
+ stream_putc(s, p->prefixlen);/* Prefix length */
+ stream_put(s, &p->u.prefix, PSIZE (p->prefixlen));
} else
stream_put_prefix_addpath(s, p, addpath_encode, addpath_tx_id);
}
diff --git a/bgpd/bgp_ecommunity.h b/bgpd/bgp_ecommunity.h
index 4cdb8b8ac8..028b7a3166 100644
--- a/bgpd/bgp_ecommunity.h
+++ b/bgpd/bgp_ecommunity.h
@@ -53,7 +53,7 @@
#define ECOMMUNITY_SIZE 8
/* Extended Communities type flag. */
-#define ECOMMUNITY_FLAG_NON_TRANSITIVE 0x40
+#define ECOMMUNITY_FLAG_NON_TRANSITIVE 0x40
/* Extended Communities attribute. */
struct ecommunity {
diff --git a/bgpd/bgp_flowspec.c b/bgpd/bgp_flowspec.c
new file mode 100644
index 0000000000..5d61175dce
--- /dev/null
+++ b/bgpd/bgp_flowspec.c
@@ -0,0 +1,78 @@
+/* BGP FlowSpec for packet handling
+ * Portions:
+ * Copyright (C) 2017 ChinaTelecom SDN Group
+ * Copyright (C) 2018 6WIND
+ *
+ * FRRouting is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * FRRouting is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "math.h"
+
+#include <zebra.h>
+#include "prefix.h"
+
+#include "bgpd/bgpd.h"
+#include "bgpd/bgp_route.h"
+#include "bgpd/bgp_flowspec.h"
+#include "bgpd/bgp_flowspec_private.h"
+
+int bgp_nlri_parse_flowspec(struct peer *peer, struct attr *attr,
+ struct bgp_nlri *packet, int withdraw)
+{
+ uint8_t *pnt;
+ uint8_t *lim;
+ afi_t afi;
+ int psize = 0;
+ uint8_t rlen;
+ struct prefix p;
+
+ /* Start processing the NLRI - there may be multiple in the MP_REACH */
+ pnt = packet->nlri;
+ lim = pnt + packet->length;
+ afi = packet->afi;
+
+ if (afi == AFI_IP6) {
+ zlog_err("BGP flowspec IPv6 not supported");
+ return -1;
+ }
+
+ if (packet->length >= FLOWSPEC_NLRI_SIZELIMIT) {
+ zlog_err("BGP flowspec nlri length maximum reached (%u)",
+ packet->length);
+ return -1;
+ }
+
+ for (; pnt < lim; pnt += psize) {
+ /* Clear prefix structure. */
+ memset(&p, 0, sizeof(struct prefix));
+
+ /* All FlowSpec NLRI begin with length. */
+ if (pnt + 1 > lim)
+ return -1;
+
+ psize = rlen = *pnt++;
+
+ /* When packet overflow occur return immediately. */
+ if (pnt + psize > lim) {
+ zlog_err("Flowspec NLRI length inconsistent ( size %u seen)",
+ psize);
+ return -1;
+ }
+ /* TODO: validate prefix
+ * and add to FIB
+ */
+ }
+ return 0;
+}
diff --git a/bgpd/bgp_flowspec.h b/bgpd/bgp_flowspec.h
new file mode 100644
index 0000000000..bf019da3aa
--- /dev/null
+++ b/bgpd/bgp_flowspec.h
@@ -0,0 +1,27 @@
+/* BGP Flowspec header for packet handling
+ * Copyright (C) 2018 6WIND
+ *
+ * FRRouting is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * FRRouting is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _FRR_BGP_FLOWSPEC_H
+#define _FRR_BGP_FLOWSPEC_H
+
+extern int bgp_nlri_parse_flowspec(struct peer *peer, struct attr *attr,
+ struct bgp_nlri *packet, int withdraw);
+
+extern void bgp_flowspec_vty_init(void);
+
+#endif /* _FRR_BGP_FLOWSPEC_H */
diff --git a/bgpd/bgp_flowspec_private.h b/bgpd/bgp_flowspec_private.h
new file mode 100644
index 0000000000..c82bb78519
--- /dev/null
+++ b/bgpd/bgp_flowspec_private.h
@@ -0,0 +1,24 @@
+/* BGP Flowspec header . private structs and defines
+ * Copyright (C) 2018 6WIND
+ *
+ * FRRouting is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * FRRouting is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _FRR_BGP_FLOWSPEC_PRIVATE_H
+#define _FRR_BGP_FLOWSPEC_PRIVATE_H
+
+#define FLOWSPEC_NLRI_SIZELIMIT 240
+
+#endif /* _FRR_BGP_FLOWSPEC_PRIVATE_H */
diff --git a/bgpd/bgp_memory.c b/bgpd/bgp_memory.c
index 64543ff019..4669fad3b7 100644
--- a/bgpd/bgp_memory.c
+++ b/bgpd/bgp_memory.c
@@ -119,3 +119,10 @@ DEFINE_MTYPE(BGPD, BGP_EVPN, "BGP EVPN Information")
DEFINE_MTYPE(BGPD, BGP_EVPN_IMPORT_RT, "BGP EVPN Import RT")
DEFINE_MTYPE(BGPD, BGP_EVPN_VRF_IMPORT_RT, "BGP EVPN VRF Import RT")
DEFINE_MTYPE(BGPD, BGP_EVPN_MACIP, "BGP EVPN MAC IP")
+
+DEFINE_MTYPE(BGPD, BGP_FLOWSPEC, "BGP flowspec")
+DEFINE_MTYPE(BGPD, BGP_FLOWSPEC_RULE, "BGP flowspec rule")
+DEFINE_MTYPE(BGPD, BGP_FLOWSPEC_RULE_STR, "BGP flowspec rule str")
+DEFINE_MTYPE(BGPD, BGP_FLOWSPEC_COMPILED, "BGP flowspec compiled")
+DEFINE_MTYPE(BGPD, BGP_FLOWSPEC_NAME, "BGP flowspec name")
+DEFINE_MTYPE(BGPD, BGP_FLOWSPEC_INDEX, "BGP flowspec index")
diff --git a/bgpd/bgp_memory.h b/bgpd/bgp_memory.h
index fae98329c6..6fa3040a19 100644
--- a/bgpd/bgp_memory.h
+++ b/bgpd/bgp_memory.h
@@ -115,4 +115,12 @@ DECLARE_MTYPE(BGP_EVPN)
DECLARE_MTYPE(BGP_EVPN_IMPORT_RT)
DECLARE_MTYPE(BGP_EVPN_VRF_IMPORT_RT)
DECLARE_MTYPE(BGP_EVPN_MACIP)
+
+DECLARE_MTYPE(BGP_FLOWSPEC)
+DECLARE_MTYPE(BGP_FLOWSPEC_RULE)
+DECLARE_MTYPE(BGP_FLOWSPEC_RULE_STR)
+DECLARE_MTYPE(BGP_FLOWSPEC_COMPILED)
+DECLARE_MTYPE(BGP_FLOWSPEC_NAME)
+DECLARE_MTYPE(BGP_FLOWSPEC_INDEX)
+
#endif /* _QUAGGA_BGP_MEMORY_H */
diff --git a/bgpd/bgp_open.c b/bgpd/bgp_open.c
index 5ec63458f5..aa98f8a557 100644
--- a/bgpd/bgp_open.c
+++ b/bgpd/bgp_open.c
@@ -146,6 +146,12 @@ void bgp_capability_vty_out(struct vty *vty, struct peer *peer,
"capabilityErrorMultiProtocolSafi",
"EVPN");
break;
+ case SAFI_FLOWSPEC:
+ json_object_string_add(
+ json_cap,
+ "capabilityErrorMultiProtocolSafi",
+ "flowspec");
+ break;
default:
json_object_int_add(
json_cap,
@@ -187,6 +193,9 @@ void bgp_capability_vty_out(struct vty *vty, struct peer *peer,
case SAFI_ENCAP:
vty_out(vty, "SAFI ENCAP");
break;
+ case SAFI_FLOWSPEC:
+ vty_out(vty, "SAFI FLOWSPEC");
+ break;
case SAFI_EVPN:
vty_out(vty, "SAFI EVPN");
break;
@@ -1166,11 +1175,13 @@ int bgp_open_option_parse(struct peer *peer, uint8_t length, int *mp_capability)
&& !peer->afc_nego[AFI_IP][SAFI_LABELED_UNICAST]
&& !peer->afc_nego[AFI_IP][SAFI_MPLS_VPN]
&& !peer->afc_nego[AFI_IP][SAFI_ENCAP]
+ && !peer->afc_nego[AFI_IP][SAFI_FLOWSPEC]
&& !peer->afc_nego[AFI_IP6][SAFI_UNICAST]
&& !peer->afc_nego[AFI_IP6][SAFI_MULTICAST]
&& !peer->afc_nego[AFI_IP6][SAFI_LABELED_UNICAST]
&& !peer->afc_nego[AFI_IP6][SAFI_MPLS_VPN]
&& !peer->afc_nego[AFI_IP6][SAFI_ENCAP]
+ && !peer->afc_nego[AFI_IP6][SAFI_FLOWSPEC]
&& !peer->afc_nego[AFI_L2VPN][SAFI_EVPN]) {
zlog_err(
"%s [Error] Configured AFI/SAFIs do not "
diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c
index 3c7bb65fd3..f0b30f0186 100644
--- a/bgpd/bgp_packet.c
+++ b/bgpd/bgp_packet.c
@@ -59,6 +59,7 @@
#include "bgpd/bgp_label.h"
#include "bgpd/bgp_io.h"
#include "bgpd/bgp_keepalives.h"
+#include "bgpd/bgp_flowspec.h"
/**
* Sets marker and type fields for a BGP message.
@@ -302,6 +303,8 @@ int bgp_nlri_parse(struct peer *peer, struct attr *attr,
packet);
case SAFI_EVPN:
return bgp_nlri_parse_evpn(peer, attr, packet, mp_withdraw);
+ case SAFI_FLOWSPEC:
+ return bgp_nlri_parse_flowspec(peer, attr, packet, mp_withdraw);
}
return -1;
}
@@ -1275,6 +1278,8 @@ static int bgp_open_receive(struct peer *peer, bgp_size_t size)
peer->afc[AFI_IP][SAFI_MULTICAST];
peer->afc_nego[AFI_IP][SAFI_LABELED_UNICAST] =
peer->afc[AFI_IP][SAFI_LABELED_UNICAST];
+ peer->afc_nego[AFI_IP][SAFI_FLOWSPEC] =
+ peer->afc[AFI_IP][SAFI_FLOWSPEC];
peer->afc_nego[AFI_IP6][SAFI_UNICAST] =
peer->afc[AFI_IP6][SAFI_UNICAST];
peer->afc_nego[AFI_IP6][SAFI_MULTICAST] =
@@ -1283,6 +1288,8 @@ static int bgp_open_receive(struct peer *peer, bgp_size_t size)
peer->afc[AFI_IP6][SAFI_LABELED_UNICAST];
peer->afc_nego[AFI_L2VPN][SAFI_EVPN] =
peer->afc[AFI_L2VPN][SAFI_EVPN];
+ peer->afc_nego[AFI_IP6][SAFI_FLOWSPEC] =
+ peer->afc[AFI_IP6][SAFI_FLOWSPEC];
}
/* When collision is detected and this peer is closed. Retrun
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index 475a8ea746..a3c7994b1b 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -80,6 +80,8 @@ static enum node_type bgp_node_type(afi_t afi, safi_t safi)
case SAFI_MPLS_VPN:
return BGP_VPNV4_NODE;
break;
+ case SAFI_FLOWSPEC:
+ return BGP_FLOWSPECV4_NODE;
default:
/* not expected */
return BGP_IPV4_NODE;
@@ -100,6 +102,8 @@ static enum node_type bgp_node_type(afi_t afi, safi_t safi)
case SAFI_MPLS_VPN:
return BGP_VPNV6_NODE;
break;
+ case SAFI_FLOWSPEC:
+ return BGP_FLOWSPECV6_NODE;
default:
/* not expected */
return BGP_IPV4_NODE;
@@ -128,6 +132,7 @@ afi_t bgp_node_afi(struct vty *vty)
case BGP_IPV6M_NODE:
case BGP_IPV6L_NODE:
case BGP_VPNV6_NODE:
+ case BGP_FLOWSPECV6_NODE:
afi = AFI_IP6;
break;
case BGP_EVPN_NODE:
@@ -161,6 +166,10 @@ safi_t bgp_node_safi(struct vty *vty)
case BGP_IPV6L_NODE:
safi = SAFI_LABELED_UNICAST;
break;
+ case BGP_FLOWSPECV4_NODE:
+ case BGP_FLOWSPECV6_NODE:
+ safi = SAFI_FLOWSPEC;
+ break;
default:
safi = SAFI_UNICAST;
break;
@@ -214,6 +223,8 @@ safi_t bgp_vty_safi_from_str(const char *safi_str)
safi = SAFI_MPLS_VPN;
else if (strmatch(safi_str, "labeled-unicast"))
safi = SAFI_LABELED_UNICAST;
+ else if (strmatch(safi_str, "flowspec"))
+ safi = SAFI_FLOWSPEC;
return safi;
}
@@ -237,6 +248,10 @@ int argv_find_and_parse_safi(struct cmd_token **argv, int argc, int *index,
ret = 1;
if (safi)
*safi = SAFI_MPLS_VPN;
+ } else if (argv_find(argv, argc, "flowspec", index)) {
+ ret = 1;
+ if (safi)
+ *safi = SAFI_FLOWSPEC;
}
return ret;
}
@@ -6645,11 +6660,11 @@ DEFPY (af_routetarget_import,
}
DEFUN_NOSH (address_family_ipv4_safi,
- address_family_ipv4_safi_cmd,
- "address-family ipv4 [<unicast|multicast|vpn|labeled-unicast>]",
- "Enter Address Family command mode\n"
- "Address Family\n"
- BGP_SAFI_WITH_LABEL_HELP_STR)
+ address_family_ipv4_safi_cmd,
+ "address-family ipv4 [<unicast|multicast|vpn|labeled-unicast|flowspec>]",
+ "Enter Address Family command mode\n"
+ "Address Family\n"
+ BGP_SAFI_WITH_LABEL_HELP_STR)
{
if (argc == 3) {
@@ -6670,11 +6685,11 @@ DEFUN_NOSH (address_family_ipv4_safi,
}
DEFUN_NOSH (address_family_ipv6_safi,
- address_family_ipv6_safi_cmd,
- "address-family ipv6 [<unicast|multicast|vpn|labeled-unicast>]",
- "Enter Address Family command mode\n"
- "Address Family\n"
- BGP_SAFI_WITH_LABEL_HELP_STR)
+ address_family_ipv6_safi_cmd,
+ "address-family ipv6 [<unicast|multicast|vpn|labeled-unicast|flowspec>]",
+ "Enter Address Family command mode\n"
+ "Address Family\n"
+ BGP_SAFI_WITH_LABEL_HELP_STR)
{
if (argc == 3) {
VTY_DECLVAR_CONTEXT(bgp, bgp);
@@ -7943,6 +7958,8 @@ const char *afi_safi_print(afi_t afi, safi_t safi)
return "IPv4 VPN";
else if (afi == AFI_IP && safi == SAFI_ENCAP)
return "IPv4 Encap";
+ else if (afi == AFI_IP && safi == SAFI_FLOWSPEC)
+ return "IPv4 Flowspec";
else if (afi == AFI_IP6 && safi == SAFI_UNICAST)
return "IPv6 Unicast";
else if (afi == AFI_IP6 && safi == SAFI_MULTICAST)
@@ -7953,6 +7970,8 @@ const char *afi_safi_print(afi_t afi, safi_t safi)
return "IPv6 VPN";
else if (afi == AFI_IP6 && safi == SAFI_ENCAP)
return "IPv6 Encap";
+ else if (afi == AFI_IP6 && safi == SAFI_FLOWSPEC)
+ return "IPv6 Flowspec";
else if (afi == AFI_L2VPN && safi == SAFI_EVPN)
return "L2VPN EVPN";
else
@@ -7977,6 +7996,8 @@ const char *afi_safi_json(afi_t afi, safi_t safi)
return "ipv4Vpn";
else if (afi == AFI_IP && safi == SAFI_ENCAP)
return "ipv4Encap";
+ else if (afi == AFI_IP && safi == SAFI_FLOWSPEC)
+ return "ipv4Flowspec";
else if (afi == AFI_IP6 && safi == SAFI_UNICAST)
return "ipv6Unicast";
else if (afi == AFI_IP6 && safi == SAFI_MULTICAST)
@@ -7987,6 +8008,8 @@ const char *afi_safi_json(afi_t afi, safi_t safi)
return "ipv6Vpn";
else if (afi == AFI_IP6 && safi == SAFI_ENCAP)
return "ipv6Encap";
+ else if (afi == AFI_IP6 && safi == SAFI_FLOWSPEC)
+ return "ipv6Flowspec";
else if (afi == AFI_L2VPN && safi == SAFI_EVPN)
return "l2VpnEvpn";
else
@@ -9001,8 +9024,12 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, uint8_t use_json,
|| p->afc_recv[AFI_IP6][SAFI_MPLS_VPN]
|| p->afc_adv[AFI_IP6][SAFI_ENCAP]
|| p->afc_recv[AFI_IP6][SAFI_ENCAP]
+ || p->afc_adv[AFI_IP6][SAFI_FLOWSPEC]
+ || p->afc_recv[AFI_IP6][SAFI_FLOWSPEC]
|| p->afc_adv[AFI_IP][SAFI_ENCAP]
|| p->afc_recv[AFI_IP][SAFI_ENCAP]
+ || p->afc_adv[AFI_IP][SAFI_FLOWSPEC]
+ || p->afc_recv[AFI_IP][SAFI_FLOWSPEC]
|| p->afc_adv[AFI_IP][SAFI_MPLS_VPN]
|| p->afc_recv[AFI_IP][SAFI_MPLS_VPN]) {
if (use_json) {
@@ -11795,6 +11822,12 @@ static struct cmd_node bgp_evpn_node = {BGP_EVPN_NODE,
static struct cmd_node bgp_evpn_vni_node = {BGP_EVPN_VNI_NODE,
"%s(config-router-af-vni)# ", 1};
+static struct cmd_node bgp_flowspecv4_node = {BGP_FLOWSPECV4_NODE,
+ "%s(config-router-af)# ", 1};
+
+static struct cmd_node bgp_flowspecv6_node = {BGP_FLOWSPECV6_NODE,
+ "%s(config-router-af-vpnv6)# ", 1};
+
static void community_list_vty(void);
static void bgp_ac_neighbor(vector comps, struct cmd_token *token)
@@ -11855,6 +11888,8 @@ void bgp_vty_init(void)
install_node(&bgp_vpnv6_node, NULL);
install_node(&bgp_evpn_node, NULL);
install_node(&bgp_evpn_vni_node, NULL);
+ install_node(&bgp_flowspecv4_node, NULL);
+ install_node(&bgp_flowspecv6_node, NULL);
/* Install default VTY commands to new nodes. */
install_default(BGP_NODE);
@@ -11866,6 +11901,8 @@ void bgp_vty_init(void)
install_default(BGP_IPV6L_NODE);
install_default(BGP_VPNV4_NODE);
install_default(BGP_VPNV6_NODE);
+ install_default(BGP_FLOWSPECV4_NODE);
+ install_default(BGP_FLOWSPECV6_NODE);
install_default(BGP_EVPN_NODE);
install_default(BGP_EVPN_VNI_NODE);
@@ -12098,6 +12135,8 @@ void bgp_vty_init(void)
install_element(BGP_IPV6L_NODE, &neighbor_activate_cmd);
install_element(BGP_VPNV4_NODE, &neighbor_activate_cmd);
install_element(BGP_VPNV6_NODE, &neighbor_activate_cmd);
+ install_element(BGP_FLOWSPECV4_NODE, &neighbor_activate_cmd);
+ install_element(BGP_FLOWSPECV6_NODE, &neighbor_activate_cmd);
install_element(BGP_EVPN_NODE, &neighbor_activate_cmd);
/* "no neighbor activate" commands. */
@@ -12110,6 +12149,8 @@ void bgp_vty_init(void)
install_element(BGP_IPV6L_NODE, &no_neighbor_activate_cmd);
install_element(BGP_VPNV4_NODE, &no_neighbor_activate_cmd);
install_element(BGP_VPNV6_NODE, &no_neighbor_activate_cmd);
+ install_element(BGP_FLOWSPECV4_NODE, &no_neighbor_activate_cmd);
+ install_element(BGP_FLOWSPECV6_NODE, &no_neighbor_activate_cmd);
install_element(BGP_EVPN_NODE, &no_neighbor_activate_cmd);
/* "neighbor peer-group" set commands. */
@@ -12121,6 +12162,10 @@ void bgp_vty_init(void)
install_element(BGP_IPV6L_NODE, &neighbor_set_peer_group_hidden_cmd);
install_element(BGP_VPNV4_NODE, &neighbor_set_peer_group_hidden_cmd);
install_element(BGP_VPNV6_NODE, &neighbor_set_peer_group_hidden_cmd);
+ install_element(BGP_FLOWSPECV4_NODE,
+ &neighbor_set_peer_group_hidden_cmd);
+ install_element(BGP_FLOWSPECV6_NODE,
+ &neighbor_set_peer_group_hidden_cmd);
/* "no neighbor peer-group unset" commands. */
install_element(BGP_NODE, &no_neighbor_set_peer_group_cmd);
@@ -12131,6 +12176,10 @@ void bgp_vty_init(void)
install_element(BGP_IPV6L_NODE, &no_neighbor_set_peer_group_hidden_cmd);
install_element(BGP_VPNV4_NODE, &no_neighbor_set_peer_group_hidden_cmd);
install_element(BGP_VPNV6_NODE, &no_neighbor_set_peer_group_hidden_cmd);
+ install_element(BGP_FLOWSPECV4_NODE,
+ &no_neighbor_set_peer_group_hidden_cmd);
+ install_element(BGP_FLOWSPECV6_NODE,
+ &no_neighbor_set_peer_group_hidden_cmd);
/* "neighbor softreconfiguration inbound" commands.*/
install_element(BGP_NODE, &neighbor_soft_reconfiguration_hidden_cmd);
@@ -12151,6 +12200,14 @@ void bgp_vty_init(void)
install_element(BGP_VPNV4_NODE, &no_neighbor_soft_reconfiguration_cmd);
install_element(BGP_VPNV6_NODE, &neighbor_soft_reconfiguration_cmd);
install_element(BGP_VPNV6_NODE, &no_neighbor_soft_reconfiguration_cmd);
+ install_element(BGP_FLOWSPECV4_NODE,
+ &neighbor_soft_reconfiguration_cmd);
+ install_element(BGP_FLOWSPECV4_NODE,
+ &no_neighbor_soft_reconfiguration_cmd);
+ install_element(BGP_FLOWSPECV6_NODE,
+ &neighbor_soft_reconfiguration_cmd);
+ install_element(BGP_FLOWSPECV6_NODE,
+ &no_neighbor_soft_reconfiguration_cmd);
/* "neighbor attribute-unchanged" commands. */
install_element(BGP_NODE, &neighbor_attr_unchanged_hidden_cmd);
@@ -12416,6 +12473,14 @@ void bgp_vty_init(void)
install_element(BGP_VPNV6_NODE, &neighbor_route_reflector_client_cmd);
install_element(BGP_VPNV6_NODE,
&no_neighbor_route_reflector_client_cmd);
+ install_element(BGP_FLOWSPECV4_NODE,
+ &neighbor_route_reflector_client_cmd);
+ install_element(BGP_FLOWSPECV4_NODE,
+ &no_neighbor_route_reflector_client_cmd);
+ install_element(BGP_FLOWSPECV6_NODE,
+ &neighbor_route_reflector_client_cmd);
+ install_element(BGP_FLOWSPECV6_NODE,
+ &no_neighbor_route_reflector_client_cmd);
install_element(BGP_EVPN_NODE, &neighbor_route_reflector_client_cmd);
install_element(BGP_EVPN_NODE, &no_neighbor_route_reflector_client_cmd);
@@ -12438,6 +12503,12 @@ void bgp_vty_init(void)
install_element(BGP_VPNV4_NODE, &no_neighbor_route_server_client_cmd);
install_element(BGP_VPNV6_NODE, &neighbor_route_server_client_cmd);
install_element(BGP_VPNV6_NODE, &no_neighbor_route_server_client_cmd);
+ install_element(BGP_FLOWSPECV4_NODE, &neighbor_route_server_client_cmd);
+ install_element(BGP_FLOWSPECV4_NODE,
+ &no_neighbor_route_server_client_cmd);
+ install_element(BGP_FLOWSPECV6_NODE, &neighbor_route_server_client_cmd);
+ install_element(BGP_FLOWSPECV6_NODE,
+ &no_neighbor_route_server_client_cmd);
/* "neighbor addpath-tx-all-paths" commands.*/
install_element(BGP_NODE, &neighbor_addpath_tx_all_paths_hidden_cmd);
@@ -12665,6 +12736,10 @@ void bgp_vty_init(void)
install_element(BGP_VPNV4_NODE, &no_neighbor_prefix_list_cmd);
install_element(BGP_VPNV6_NODE, &neighbor_prefix_list_cmd);
install_element(BGP_VPNV6_NODE, &no_neighbor_prefix_list_cmd);
+ install_element(BGP_FLOWSPECV4_NODE, &neighbor_prefix_list_cmd);
+ install_element(BGP_FLOWSPECV4_NODE, &no_neighbor_prefix_list_cmd);
+ install_element(BGP_FLOWSPECV6_NODE, &neighbor_prefix_list_cmd);
+ install_element(BGP_FLOWSPECV6_NODE, &no_neighbor_prefix_list_cmd);
/* "neighbor filter-list" commands. */
install_element(BGP_NODE, &neighbor_filter_list_hidden_cmd);
@@ -12685,6 +12760,10 @@ void bgp_vty_init(void)
install_element(BGP_VPNV4_NODE, &no_neighbor_filter_list_cmd);
install_element(BGP_VPNV6_NODE, &neighbor_filter_list_cmd);
install_element(BGP_VPNV6_NODE, &no_neighbor_filter_list_cmd);
+ install_element(BGP_FLOWSPECV4_NODE, &neighbor_filter_list_cmd);
+ install_element(BGP_FLOWSPECV4_NODE, &no_neighbor_filter_list_cmd);
+ install_element(BGP_FLOWSPECV6_NODE, &neighbor_filter_list_cmd);
+ install_element(BGP_FLOWSPECV6_NODE, &no_neighbor_filter_list_cmd);
/* "neighbor route-map" commands. */
install_element(BGP_NODE, &neighbor_route_map_hidden_cmd);
@@ -12705,6 +12784,10 @@ void bgp_vty_init(void)
install_element(BGP_VPNV4_NODE, &no_neighbor_route_map_cmd);
install_element(BGP_VPNV6_NODE, &neighbor_route_map_cmd);
install_element(BGP_VPNV6_NODE, &no_neighbor_route_map_cmd);
+ install_element(BGP_FLOWSPECV4_NODE, &neighbor_route_map_cmd);
+ install_element(BGP_FLOWSPECV4_NODE, &no_neighbor_route_map_cmd);
+ install_element(BGP_FLOWSPECV6_NODE, &neighbor_route_map_cmd);
+ install_element(BGP_FLOWSPECV6_NODE, &no_neighbor_route_map_cmd);
install_element(BGP_EVPN_NODE, &neighbor_route_map_cmd);
install_element(BGP_EVPN_NODE, &no_neighbor_route_map_cmd);
@@ -12853,6 +12936,8 @@ void bgp_vty_init(void)
install_element(BGP_IPV6L_NODE, &exit_address_family_cmd);
install_element(BGP_VPNV4_NODE, &exit_address_family_cmd);
install_element(BGP_VPNV6_NODE, &exit_address_family_cmd);
+ install_element(BGP_FLOWSPECV4_NODE, &exit_address_family_cmd);
+ install_element(BGP_FLOWSPECV6_NODE, &exit_address_family_cmd);
install_element(BGP_EVPN_NODE, &exit_address_family_cmd);
/* "clear ip bgp commands" */
diff --git a/bgpd/bgp_vty.h b/bgpd/bgp_vty.h
index 7a9546e3ef..afb85f112b 100644
--- a/bgpd/bgp_vty.h
+++ b/bgpd/bgp_vty.h
@@ -36,11 +36,12 @@ struct bgp;
#define BGP_AFI_SAFI_CMD_STR BGP_AFI_CMD_STR" "BGP_SAFI_CMD_STR
#define BGP_AFI_SAFI_HELP_STR BGP_AFI_HELP_STR BGP_SAFI_HELP_STR
-#define BGP_SAFI_WITH_LABEL_CMD_STR "<unicast|multicast|vpn|labeled-unicast>"
+#define BGP_SAFI_WITH_LABEL_CMD_STR "<unicast|multicast|vpn|labeled-unicast|flowspec>"
#define BGP_SAFI_WITH_LABEL_HELP_STR \
"Address Family modifier\n" \
"Address Family modifier\n" \
"Address Family modifier\n" \
+ "Address Family modifier\n" \
"Address Family modifier\n"
extern void bgp_vty_init(void);
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index 97f0ffcf2c..ad4e7dc34c 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -80,6 +80,8 @@
#include "bgpd/bgp_keepalives.h"
#include "bgpd/bgp_io.h"
#include "bgpd/bgp_ecommunity.h"
+#include "bgpd/bgp_flowspec.h"
+
DEFINE_MTYPE_STATIC(BGPD, PEER_TX_SHUTDOWN_MSG, "Peer shutdown message (TX)");
DEFINE_QOBJ_TYPE(bgp_master)
@@ -1626,6 +1628,8 @@ void peer_as_change(struct peer *peer, as_t as, int as_specified)
PEER_FLAG_REFLECTOR_CLIENT);
UNSET_FLAG(peer->af_flags[AFI_IP][SAFI_ENCAP],
PEER_FLAG_REFLECTOR_CLIENT);
+ UNSET_FLAG(peer->af_flags[AFI_IP][SAFI_FLOWSPEC],
+ PEER_FLAG_REFLECTOR_CLIENT);
UNSET_FLAG(peer->af_flags[AFI_IP6][SAFI_UNICAST],
PEER_FLAG_REFLECTOR_CLIENT);
UNSET_FLAG(peer->af_flags[AFI_IP6][SAFI_MULTICAST],
@@ -1636,6 +1640,8 @@ void peer_as_change(struct peer *peer, as_t as, int as_specified)
PEER_FLAG_REFLECTOR_CLIENT);
UNSET_FLAG(peer->af_flags[AFI_IP6][SAFI_ENCAP],
PEER_FLAG_REFLECTOR_CLIENT);
+ UNSET_FLAG(peer->af_flags[AFI_IP6][SAFI_FLOWSPEC],
+ PEER_FLAG_REFLECTOR_CLIENT);
UNSET_FLAG(peer->af_flags[AFI_L2VPN][SAFI_EVPN],
PEER_FLAG_REFLECTOR_CLIENT);
}
@@ -3641,11 +3647,13 @@ int peer_active(struct peer *peer)
if (peer->afc[AFI_IP][SAFI_UNICAST] || peer->afc[AFI_IP][SAFI_MULTICAST]
|| peer->afc[AFI_IP][SAFI_LABELED_UNICAST]
|| peer->afc[AFI_IP][SAFI_MPLS_VPN] || peer->afc[AFI_IP][SAFI_ENCAP]
+ || peer->afc[AFI_IP][SAFI_FLOWSPEC]
|| peer->afc[AFI_IP6][SAFI_UNICAST]
|| peer->afc[AFI_IP6][SAFI_MULTICAST]
|| peer->afc[AFI_IP6][SAFI_LABELED_UNICAST]
|| peer->afc[AFI_IP6][SAFI_MPLS_VPN]
|| peer->afc[AFI_IP6][SAFI_ENCAP]
+ || peer->afc[AFI_IP6][SAFI_FLOWSPEC]
|| peer->afc[AFI_L2VPN][SAFI_EVPN])
return 1;
return 0;
@@ -3659,11 +3667,13 @@ int peer_active_nego(struct peer *peer)
|| peer->afc_nego[AFI_IP][SAFI_LABELED_UNICAST]
|| peer->afc_nego[AFI_IP][SAFI_MPLS_VPN]
|| peer->afc_nego[AFI_IP][SAFI_ENCAP]
+ || peer->afc_nego[AFI_IP][SAFI_FLOWSPEC]
|| peer->afc_nego[AFI_IP6][SAFI_UNICAST]
|| peer->afc_nego[AFI_IP6][SAFI_MULTICAST]
|| peer->afc_nego[AFI_IP6][SAFI_LABELED_UNICAST]
|| peer->afc_nego[AFI_IP6][SAFI_MPLS_VPN]
|| peer->afc_nego[AFI_IP6][SAFI_ENCAP]
+ || peer->afc_nego[AFI_IP6][SAFI_FLOWSPEC]
|| peer->afc_nego[AFI_L2VPN][SAFI_EVPN])
return 1;
return 0;
@@ -7100,6 +7110,8 @@ static void bgp_config_write_family(struct vty *vty, struct bgp *bgp, afi_t afi,
vty_frame(vty, "ipv4 vpn");
else if (safi == SAFI_ENCAP)
vty_frame(vty, "ipv4 encap");
+ else if (safi == SAFI_FLOWSPEC)
+ vty_frame(vty, "ipv4 flowspec");
} else if (afi == AFI_IP6) {
if (safi == SAFI_UNICAST)
vty_frame(vty, "ipv6 unicast");
@@ -7111,6 +7123,8 @@ static void bgp_config_write_family(struct vty *vty, struct bgp *bgp, afi_t afi,
vty_frame(vty, "ipv6 vpn");
else if (safi == SAFI_ENCAP)
vty_frame(vty, "ipv6 encap");
+ else if (safi == SAFI_FLOWSPEC)
+ vty_frame(vty, "ipv6 flowspec");
} else if (afi == AFI_L2VPN) {
if (safi == SAFI_EVPN)
vty_frame(vty, "l2vpn evpn");
@@ -7437,6 +7451,9 @@ int bgp_config_write(struct vty *vty)
/* ENCAPv4 configuration. */
bgp_config_write_family(vty, bgp, AFI_IP, SAFI_ENCAP);
+ /* FLOWSPEC v4 configuration. */
+ bgp_config_write_family(vty, bgp, AFI_IP, SAFI_FLOWSPEC);
+
/* IPv6 unicast configuration. */
bgp_config_write_family(vty, bgp, AFI_IP6, SAFI_UNICAST);
@@ -7453,6 +7470,9 @@ int bgp_config_write(struct vty *vty)
/* ENCAPv6 configuration. */
bgp_config_write_family(vty, bgp, AFI_IP6, SAFI_ENCAP);
+ /* FLOWSPEC v6 configuration. */
+ bgp_config_write_family(vty, bgp, AFI_IP6, SAFI_FLOWSPEC);
+
/* EVPN configuration. */
bgp_config_write_family(vty, bgp, AFI_L2VPN, SAFI_EVPN);
@@ -7610,6 +7630,7 @@ void bgp_init(void)
rfapi_init();
#endif
bgp_ethernetvpn_init();
+ bgp_flowspec_vty_init();
/* Access list initialize. */
access_list_init();
diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h
index 10d6e03976..40f887b86d 100644
--- a/bgpd/bgpd.h
+++ b/bgpd/bgpd.h
@@ -84,6 +84,8 @@ enum bgp_af_index {
BGP_AF_L2VPN_EVPN,
BGP_AF_IPV4_LBL_UNICAST,
BGP_AF_IPV6_LBL_UNICAST,
+ BGP_AF_IPV4_FLOWSPEC,
+ BGP_AF_IPV6_FLOWSPEC,
BGP_AF_MAX
};
@@ -1558,6 +1560,8 @@ static inline int afindex(afi_t afi, safi_t safi)
case SAFI_ENCAP:
return BGP_AF_IPV4_ENCAP;
break;
+ case SAFI_FLOWSPEC:
+ return BGP_AF_IPV4_FLOWSPEC;
default:
return BGP_AF_MAX;
break;
@@ -1580,6 +1584,8 @@ static inline int afindex(afi_t afi, safi_t safi)
case SAFI_ENCAP:
return BGP_AF_IPV6_ENCAP;
break;
+ case SAFI_FLOWSPEC:
+ return BGP_AF_IPV6_FLOWSPEC;
default:
return BGP_AF_MAX;
break;
@@ -1616,6 +1622,7 @@ static inline int peer_afi_active_nego(const struct peer *peer, afi_t afi)
|| peer->afc_nego[afi][SAFI_LABELED_UNICAST]
|| peer->afc_nego[afi][SAFI_MPLS_VPN]
|| peer->afc_nego[afi][SAFI_ENCAP]
+ || peer->afc_nego[afi][SAFI_FLOWSPEC]
|| peer->afc_nego[afi][SAFI_EVPN])
return 1;
return 0;
@@ -1628,12 +1635,14 @@ static inline int peer_group_af_configured(struct peer_group *group)
if (peer->afc[AFI_IP][SAFI_UNICAST] || peer->afc[AFI_IP][SAFI_MULTICAST]
|| peer->afc[AFI_IP][SAFI_LABELED_UNICAST]
+ || peer->afc[AFI_IP][SAFI_FLOWSPEC]
|| peer->afc[AFI_IP][SAFI_MPLS_VPN] || peer->afc[AFI_IP][SAFI_ENCAP]
|| peer->afc[AFI_IP6][SAFI_UNICAST]
|| peer->afc[AFI_IP6][SAFI_MULTICAST]
|| peer->afc[AFI_IP6][SAFI_LABELED_UNICAST]
|| peer->afc[AFI_IP6][SAFI_MPLS_VPN]
|| peer->afc[AFI_IP6][SAFI_ENCAP]
+ || peer->afc[AFI_IP6][SAFI_FLOWSPEC]
|| peer->afc[AFI_L2VPN][SAFI_EVPN])
return 1;
return 0;
diff --git a/lib/command.c b/lib/command.c
index 5697c1d812..7c7fddeea5 100644
--- a/lib/command.c
+++ b/lib/command.c
@@ -118,6 +118,10 @@ const char *node_names[] = {
"link-params", // LINK_PARAMS_NODE,
"bgp evpn vni", // BGP_EVPN_VNI_NODE,
"rpki", // RPKI_NODE
+ "bgp ipv4 flowspec", /* BGP_FLOWSPECV4_NODE
+ */
+ "bgp ipv6 flowspec", /* BGP_FLOWSPECV6_NODE
+ */
};
/* Command vector which includes some level of command lists. Normally
@@ -948,6 +952,8 @@ enum node_type node_parent(enum node_type node)
switch (node) {
case BGP_VPNV4_NODE:
case BGP_VPNV6_NODE:
+ case BGP_FLOWSPECV4_NODE:
+ case BGP_FLOWSPECV6_NODE:
case BGP_VRF_POLICY_NODE:
case BGP_VNC_DEFAULTS_NODE:
case BGP_VNC_NVE_GROUP_NODE:
@@ -1318,6 +1324,8 @@ void cmd_exit(struct vty *vty)
case BGP_IPV4L_NODE:
case BGP_VPNV4_NODE:
case BGP_VPNV6_NODE:
+ case BGP_FLOWSPECV4_NODE:
+ case BGP_FLOWSPECV6_NODE:
case BGP_VRF_POLICY_NODE:
case BGP_VNC_DEFAULTS_NODE:
case BGP_VNC_NVE_GROUP_NODE:
@@ -1394,6 +1402,8 @@ DEFUN (config_end,
case BGP_VNC_L2_GROUP_NODE:
case BGP_VPNV4_NODE:
case BGP_VPNV6_NODE:
+ case BGP_FLOWSPECV4_NODE:
+ case BGP_FLOWSPECV6_NODE:
case BGP_IPV4_NODE:
case BGP_IPV4M_NODE:
case BGP_IPV4L_NODE:
diff --git a/lib/command.h b/lib/command.h
index 95d8ee99df..a7fa3a1692 100644
--- a/lib/command.h
+++ b/lib/command.h
@@ -142,6 +142,8 @@ enum node_type {
BGP_EVPN_VNI_NODE, /* BGP EVPN VNI */
RPKI_NODE, /* RPKI node for configuration of RPKI cache server
connections.*/
+ BGP_FLOWSPECV4_NODE, /* BGP IPv4 FLOWSPEC Address-Family */
+ BGP_FLOWSPECV6_NODE, /* BGP IPv6 FLOWSPEC Address-Family */
NODE_TYPE_MAX, /* maximum */
};
diff --git a/lib/prefix.c b/lib/prefix.c
index 515b4dcb5e..ed55fac883 100644
--- a/lib/prefix.c
+++ b/lib/prefix.c
@@ -523,6 +523,8 @@ const char *safi2str(safi_t safi)
return "evpn";
case SAFI_LABELED_UNICAST:
return "labeled-unicast";
+ case SAFI_FLOWSPEC:
+ return "flowspec";
default:
return "unknown";
}
diff --git a/lib/zebra.h b/lib/zebra.h
index 3887602231..f4f104299d 100644
--- a/lib/zebra.h
+++ b/lib/zebra.h
@@ -462,7 +462,8 @@ typedef enum {
IANA_SAFI_LABELED_UNICAST = 4,
IANA_SAFI_ENCAP = 7,
IANA_SAFI_EVPN = 70,
- IANA_SAFI_MPLS_VPN = 128
+ IANA_SAFI_MPLS_VPN = 128,
+ IANA_SAFI_FLOWSPEC = 133
} iana_safi_t;
/* Default Administrative Distance of each protocol. */
@@ -548,6 +549,8 @@ static inline safi_t safi_iana2int(iana_safi_t safi)
return SAFI_EVPN;
case IANA_SAFI_LABELED_UNICAST:
return SAFI_LABELED_UNICAST;
+ case IANA_SAFI_FLOWSPEC:
+ return SAFI_FLOWSPEC;
default:
return SAFI_MAX;
}
@@ -568,6 +571,8 @@ static inline iana_safi_t safi_int2iana(safi_t safi)
return IANA_SAFI_EVPN;
case SAFI_LABELED_UNICAST:
return IANA_SAFI_LABELED_UNICAST;
+ case SAFI_FLOWSPEC:
+ return IANA_SAFI_FLOWSPEC;
default:
return IANA_SAFI_RESERVED;
}