This work is derived from a work done by China-Telecom.
That initial work can be found in [0].
As the gap between frr and quagga is important, a reworks has been
done in the meantime.
The initial work consists of bringing the following:
- Bringing the client side of flowspec.
- the enhancement of address-family ipv4/ipv6 flowspec
- partial data path handling at reception has been prepared
- the support for ipv4 flowspec or ipv6 flowspec in BGP open messages,
and the internals of BGP has been done.
- the memory contexts necessary for flowspec has been provisioned
In addition to this work, the following has been done:
- the complement of adaptation for FS safi in bgp code
- the code checkstyle has been reworked so as to match frr checkstyle
- the processing of IPv6 FS NLRI is prevented
- the processing of FS NLRI is stopped ( temporary)
[0] https://github.com/chinatelecom-sdn-group/quagga_flowspec/
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
Signed-off-by: jaydom <chinatelecom-sdn-group@github.com>
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 \
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@
#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[] = {
/* 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 */
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;
}
stream_put(s, &attr->mp_nexthop_global,
IPV6_MAX_BYTELEN);
break;
+ case SAFI_FLOWSPEC:
+ stream_putc(s, 0); /* no nexthop for flowspec */
default:
break;
}
} 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);
}
#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 {
--- /dev/null
+/* 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;
+}
--- /dev/null
+/* 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 */
--- /dev/null
+/* 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 */
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")
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 */
"capabilityErrorMultiProtocolSafi",
"EVPN");
break;
+ case SAFI_FLOWSPEC:
+ json_object_string_add(
+ json_cap,
+ "capabilityErrorMultiProtocolSafi",
+ "flowspec");
+ break;
default:
json_object_int_add(
json_cap,
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;
&& !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 "
#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.
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;
}
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] =
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
case SAFI_MPLS_VPN:
return BGP_VPNV4_NODE;
break;
+ case SAFI_FLOWSPEC:
+ return BGP_FLOWSPECV4_NODE;
default:
/* not expected */
return BGP_IPV4_NODE;
case SAFI_MPLS_VPN:
return BGP_VPNV6_NODE;
break;
+ case SAFI_FLOWSPEC:
+ return BGP_FLOWSPECV6_NODE;
default:
/* not expected */
return BGP_IPV4_NODE;
case BGP_IPV6M_NODE:
case BGP_IPV6L_NODE:
case BGP_VPNV6_NODE:
+ case BGP_FLOWSPECV6_NODE:
afi = AFI_IP6;
break;
case BGP_EVPN_NODE:
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;
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;
}
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;
}
}
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) {
}
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);
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)
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
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)
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
|| 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) {
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)
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);
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);
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. */
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. */
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);
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);
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);
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);
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);
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);
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);
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);
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" */
#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);
#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)
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],
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);
}
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;
|| 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;
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");
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");
/* 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);
/* 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);
rfapi_init();
#endif
bgp_ethernetvpn_init();
+ bgp_flowspec_vty_init();
/* Access list initialize. */
access_list_init();
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
};
case SAFI_ENCAP:
return BGP_AF_IPV4_ENCAP;
break;
+ case SAFI_FLOWSPEC:
+ return BGP_AF_IPV4_FLOWSPEC;
default:
return BGP_AF_MAX;
break;
case SAFI_ENCAP:
return BGP_AF_IPV6_ENCAP;
break;
+ case SAFI_FLOWSPEC:
+ return BGP_AF_IPV6_FLOWSPEC;
default:
return BGP_AF_MAX;
break;
|| 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;
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;
"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
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:
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:
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:
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 */
};
return "evpn";
case SAFI_LABELED_UNICAST:
return "labeled-unicast";
+ case SAFI_FLOWSPEC:
+ return "flowspec";
default:
return "unknown";
}
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. */
return SAFI_EVPN;
case IANA_SAFI_LABELED_UNICAST:
return SAFI_LABELED_UNICAST;
+ case IANA_SAFI_FLOWSPEC:
+ return SAFI_FLOWSPEC;
default:
return SAFI_MAX;
}
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;
}