bgpd: add flowspec feature

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>
This commit is contained in:
jaydom 2017-01-23 10:45:30 +08:00 committed by Philippe Guibert
parent 9a14899b0a
commit 7c40bf391c
18 changed files with 332 additions and 15 deletions

View File

@ -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@

View File

@ -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);
}

View File

@ -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 {

78
bgpd/bgp_flowspec.c Normal file
View File

@ -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;
}

27
bgpd/bgp_flowspec.h Normal file
View File

@ -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 */

View File

@ -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 */

View File

@ -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")

View File

@ -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 */

View File

@ -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 "

View File

@ -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

View File

@ -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" */

View File

@ -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);

View File

@ -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();

View File

@ -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;

View File

@ -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:

View File

@ -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 */
};

View File

@ -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";
}

View File

@ -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;
}