mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-04-28 17:01:51 +00:00
bgpd/bmp: BMP implementation
This implements BMP. There's no fine-grained history here, the non-BMP preparations are already split out from here so all that remains is BMP proper. Signed-off-by: David Lamparter <equinox@diac24.net>
This commit is contained in:
parent
0ba4eeec22
commit
ed18356f1f
2295
bgpd/bgp_bmp.c
2295
bgpd/bgp_bmp.c
File diff suppressed because it is too large
Load Diff
296
bgpd/bgp_bmp.h
296
bgpd/bgp_bmp.h
@ -1,17 +1,16 @@
|
||||
/* BMP support.
|
||||
* Copyright (C) 2018 Yasuhiro Ohara
|
||||
* Copyright (C) 2019 David Lamparter for NetDEF, Inc.
|
||||
*
|
||||
* This file is part of GNU Zebra.
|
||||
* This program 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 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* GNU Zebra 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.
|
||||
*
|
||||
* GNU Zebra 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.
|
||||
* This program 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
|
||||
@ -21,6 +20,12 @@
|
||||
#ifndef _BGP_BMP_H_
|
||||
#define _BGP_BMP_H_
|
||||
|
||||
#include "zebra.h"
|
||||
#include "typesafe.h"
|
||||
#include "pullwr.h"
|
||||
#include "qobj.h"
|
||||
#include "resolver.h"
|
||||
|
||||
#define BMP_VERSION_3 3
|
||||
|
||||
#define BMP_LENGTH_POS 1
|
||||
@ -38,30 +43,261 @@
|
||||
|
||||
/* bmp->state */
|
||||
#define BMP_None 0
|
||||
#define BMP_Initiation 1
|
||||
#define BMP_PeerUp 2
|
||||
#define BMP_MonitorInit 3
|
||||
#define BMP_Monitor 4
|
||||
#define BMP_EndofRIB 5
|
||||
#define BMP_Mirror 6
|
||||
#define BMP_Run 3
|
||||
|
||||
struct bmp
|
||||
{
|
||||
int socket;
|
||||
char remote[SU_ADDRSTRLEN];
|
||||
struct thread *t_read;
|
||||
struct thread *t_write;
|
||||
struct thread *t_event;
|
||||
/* This one is for BMP Route Monitoring messages, i.e. delivering updates
|
||||
* in somewhat processed (as opposed to fully raw, see mirroring below) form.
|
||||
* RFC explicitly says that we can skip old updates if we haven't sent them out
|
||||
* yet and another newer update for the same prefix arrives.
|
||||
*
|
||||
* So, at most one of these can exist for each (bgp, afi, safi, prefix, peerid)
|
||||
* tuple; if some prefix is "re-added" to the queue, the existing entry is
|
||||
* instead moved to the end of the queue. This ensures that the queue size is
|
||||
* bounded by the BGP table size.
|
||||
*
|
||||
* bmp_qlist is the queue itself while bmp_qhash is used to efficiently check
|
||||
* whether a tuple is already on the list. The queue is maintained per
|
||||
* bmp_target.
|
||||
*
|
||||
* refcount = number of "struct bmp *" whose queue position is before this
|
||||
* entry, i.e. number of BMP sessions where we still want to send this out.
|
||||
* Decremented on send so we know when we're done with an entry (i.e. this
|
||||
* always happens from the front of the queue.)
|
||||
*/
|
||||
|
||||
int state;
|
||||
struct stream_fifo *obuf;
|
||||
PREDECL_DLIST(bmp_qlist)
|
||||
PREDECL_HASH(bmp_qhash)
|
||||
|
||||
struct bmp_queue_entry {
|
||||
struct bmp_qlist_item bli;
|
||||
struct bmp_qhash_item bhi;
|
||||
|
||||
struct prefix p;
|
||||
uint64_t peerid;
|
||||
afi_t afi;
|
||||
safi_t safi;
|
||||
|
||||
size_t refcount;
|
||||
};
|
||||
|
||||
#define BMP_EVENT_ADD(X) \
|
||||
do { \
|
||||
if ((X)->t_event == NULL) \
|
||||
thread_add_event(bm->master, bmp_event, (X), 0, \
|
||||
&(X)->t_event); \
|
||||
} while (0)
|
||||
/* This is for BMP Route Mirroring, which feeds fully raw BGP PDUs out to BMP
|
||||
* receivers. So, this goes directly off packet RX/TX handling instead of
|
||||
* grabbing bits from tables.
|
||||
*
|
||||
* There is *one* queue for each "struct bgp *" where we throw everything on,
|
||||
* with a size limit. Refcount works the same as for monitoring above.
|
||||
*/
|
||||
|
||||
PREDECL_LIST(bmp_mirrorq)
|
||||
|
||||
struct bmp_mirrorq {
|
||||
struct bmp_mirrorq_item bmi;
|
||||
|
||||
size_t refcount;
|
||||
uint64_t peerid;
|
||||
struct timeval tv;
|
||||
|
||||
size_t len;
|
||||
uint8_t data[0];
|
||||
};
|
||||
|
||||
enum {
|
||||
BMP_AFI_INACTIVE = 0,
|
||||
BMP_AFI_NEEDSYNC,
|
||||
BMP_AFI_SYNC,
|
||||
BMP_AFI_LIVE,
|
||||
};
|
||||
|
||||
PREDECL_LIST(bmp_session)
|
||||
|
||||
struct bmp_active;
|
||||
struct bmp_targets;
|
||||
|
||||
/* an established BMP session to a peer */
|
||||
struct bmp {
|
||||
struct bmp_session_item bsi;
|
||||
struct bmp_targets *targets;
|
||||
struct bmp_active *active;
|
||||
|
||||
int socket;
|
||||
char remote[SU_ADDRSTRLEN + 6];
|
||||
struct thread *t_read;
|
||||
|
||||
struct pullwr *pullwr;
|
||||
|
||||
int state;
|
||||
|
||||
/* queue positions must remain synced with refcounts in the items.
|
||||
* Whenever appending a queue item, we need to know the correct number
|
||||
* of "struct bmp *" that want it, and when moving these positions
|
||||
* ahead we need to make sure that refcount is decremented. Also, on
|
||||
* disconnects we need to walk the queue and drop our reference.
|
||||
*/
|
||||
struct bmp_queue_entry *queuepos;
|
||||
struct bmp_mirrorq *mirrorpos;
|
||||
bool mirror_lost;
|
||||
|
||||
/* enum BMP_AFI_* */
|
||||
uint8_t afistate[AFI_MAX][SAFI_MAX];
|
||||
|
||||
/* counters for the various BMP packet types */
|
||||
uint64_t cnt_update, cnt_mirror;
|
||||
/* number of times this peer wasn't fast enough in consuming the
|
||||
* mirror queue
|
||||
*/
|
||||
uint64_t cnt_mirror_overruns;
|
||||
struct timeval t_up;
|
||||
|
||||
/* synchronization / startup works by repeatedly finding the next
|
||||
* table entry, the sync* fields note down what we sent last
|
||||
*/
|
||||
struct prefix syncpos;
|
||||
uint64_t syncpeerid;
|
||||
afi_t syncafi;
|
||||
safi_t syncsafi;
|
||||
};
|
||||
|
||||
/* config & state for an active outbound connection. When the connection
|
||||
* succeeds, "bmp" is set up.
|
||||
*/
|
||||
|
||||
PREDECL_SORTLIST_UNIQ(bmp_actives)
|
||||
|
||||
#define BMP_DFLT_MINRETRY 30000
|
||||
#define BMP_DFLT_MAXRETRY 720000
|
||||
|
||||
struct bmp_active {
|
||||
struct bmp_actives_item bai;
|
||||
struct bmp_targets *targets;
|
||||
struct bmp *bmp;
|
||||
|
||||
char *hostname;
|
||||
int port;
|
||||
unsigned minretry, maxretry;
|
||||
|
||||
struct resolver_query resq;
|
||||
|
||||
unsigned curretry;
|
||||
unsigned addrpos, addrtotal;
|
||||
union sockunion addrs[8];
|
||||
int socket;
|
||||
struct thread *t_timer, *t_read, *t_write;
|
||||
};
|
||||
|
||||
/* config & state for passive / listening sockets */
|
||||
PREDECL_SORTLIST_UNIQ(bmp_listeners)
|
||||
|
||||
struct bmp_listener {
|
||||
struct bmp_listeners_item bli;
|
||||
|
||||
struct bmp_targets *targets;
|
||||
|
||||
union sockunion addr;
|
||||
int port;
|
||||
|
||||
struct thread *t_accept;
|
||||
int sock;
|
||||
};
|
||||
|
||||
/* bmp_targets - plural since it may contain multiple bmp_listener &
|
||||
* bmp_active items. If they have the same config, BMP session should be
|
||||
* put in the same targets since that's a bit more effective.
|
||||
*/
|
||||
PREDECL_SORTLIST_UNIQ(bmp_targets)
|
||||
|
||||
struct bmp_targets {
|
||||
struct bmp_targets_item bti;
|
||||
|
||||
struct bmp_bgp *bmpbgp;
|
||||
struct bgp *bgp;
|
||||
char *name;
|
||||
|
||||
struct bmp_listeners_head listeners;
|
||||
|
||||
char *acl_name;
|
||||
char *acl6_name;
|
||||
#define BMP_STAT_DEFAULT_TIMER 60000
|
||||
int stat_msec;
|
||||
|
||||
/* only IPv4 & IPv6 / unicast & multicast supported for now */
|
||||
#define BMP_MON_PREPOLICY (1 << 0)
|
||||
#define BMP_MON_POSTPOLICY (1 << 1)
|
||||
uint8_t afimon[AFI_MAX][SAFI_MAX];
|
||||
bool mirror;
|
||||
|
||||
struct bmp_actives_head actives;
|
||||
|
||||
struct thread *t_stats;
|
||||
struct bmp_session_head sessions;
|
||||
|
||||
struct bmp_qhash_head updhash;
|
||||
struct bmp_qlist_head updlist;
|
||||
|
||||
uint64_t cnt_accept, cnt_aclrefused;
|
||||
|
||||
QOBJ_FIELDS
|
||||
};
|
||||
DECLARE_QOBJ_TYPE(bmp_targets)
|
||||
|
||||
/* per struct peer * data. Lookup by peer->qobj_node.nid, created on demand,
|
||||
* deleted in peer_backward hook. */
|
||||
PREDECL_HASH(bmp_peerh)
|
||||
|
||||
struct bmp_bgp_peer {
|
||||
struct bmp_peerh_item bpi;
|
||||
|
||||
uint64_t peerid;
|
||||
/* struct peer *peer; */
|
||||
|
||||
uint8_t *open_rx;
|
||||
size_t open_rx_len;
|
||||
|
||||
uint8_t *open_tx;
|
||||
size_t open_tx_len;
|
||||
};
|
||||
|
||||
/* per struct bgp * data */
|
||||
PREDECL_HASH(bmp_bgph)
|
||||
|
||||
struct bmp_bgp {
|
||||
struct bmp_bgph_item bbi;
|
||||
|
||||
struct bgp *bgp;
|
||||
struct bmp_targets_head targets;
|
||||
|
||||
struct bmp_mirrorq_head mirrorq;
|
||||
size_t mirror_qsize, mirror_qsizemax;
|
||||
|
||||
size_t mirror_qsizelimit;
|
||||
};
|
||||
|
||||
enum {
|
||||
BMP_PEERDOWN_LOCAL_NOTIFY = 1,
|
||||
BMP_PEERDOWN_LOCAL_FSM = 2,
|
||||
BMP_PEERDOWN_REMOTE_NOTIFY = 3,
|
||||
BMP_PEERDOWN_REMOTE_CLOSE = 4,
|
||||
BMP_PEERDOWN_ENDMONITOR = 5,
|
||||
};
|
||||
|
||||
enum {
|
||||
BMP_STATS_PFX_REJECTED = 0,
|
||||
BMP_STATS_PFX_DUP_ADV = 1,
|
||||
BMP_STATS_PFX_DUP_WITHDRAW = 2,
|
||||
BMP_STATS_UPD_LOOP_CLUSTER = 3,
|
||||
BMP_STATS_UPD_LOOP_ASPATH = 4,
|
||||
BMP_STATS_UPD_LOOP_ORIGINATOR = 5,
|
||||
BMP_STATS_UPD_LOOP_CONFED = 6,
|
||||
BMP_STATS_SIZE_ADJ_RIB_IN = 7,
|
||||
BMP_STATS_SIZE_LOC_RIB = 8,
|
||||
BMP_STATS_SIZE_ADJ_RIB_IN_SAFI = 9,
|
||||
BMP_STATS_SIZE_LOC_RIB_IN_SAFI = 10,
|
||||
BMP_STATS_UPD_7606_WITHDRAW = 11,
|
||||
BMP_STATS_PFX_7606_WITHDRAW = 12,
|
||||
BMP_STATS_UPD_DUP = 13,
|
||||
BMP_STATS_FRR_NH_INVALID = 65531,
|
||||
};
|
||||
|
||||
DECLARE_MGROUP(BMP)
|
||||
|
||||
#endif /*_BGP_BMP_H_*/
|
||||
|
@ -27,6 +27,7 @@ vtysh_scan += \
|
||||
|
||||
# can be loaded as DSO - always include for vtysh
|
||||
vtysh_scan += $(top_srcdir)/bgpd/bgp_rpki.c
|
||||
vtysh_scan += $(top_srcdir)/bgpd/bgp_bmp.c
|
||||
|
||||
if ENABLE_BGP_VNC
|
||||
vtysh_scan += \
|
||||
@ -219,6 +220,7 @@ bgpd_bgpd_rpki_la_LDFLAGS = -avoid-version -module -shared -export-dynamic
|
||||
bgpd_bgpd_rpki_la_LIBADD = $(RTRLIB_LIBS)
|
||||
|
||||
bgpd_bgpd_bmp_la_SOURCES = bgpd/bgp_bmp.c
|
||||
bgpd_bgpd_bmp_la_LIBADD = lib/libfrrcares.la
|
||||
bgpd_bgpd_bmp_la_LDFLAGS = -avoid-version -module -shared -export-dynamic
|
||||
|
||||
bgpd/bgp_evpn_vty_clippy.c: $(CLIPPY_DEPS)
|
||||
@ -234,3 +236,5 @@ bgpd/bgp_routemap.$(OBJEXT): bgpd/bgp_routemap_clippy.c
|
||||
bgpd/bgp_rpki_clippy.c: $(CLIPPY_DEPS)
|
||||
$(AUTOMAKE_DUMMY)bgpd/bgpd_bgpd_rpki_la-bgp_rpki.lo: bgpd/bgp_rpki_clippy.c
|
||||
$(AUTOMAKE_DUMMY)bgpd/bgpd_rpki_la-bgp_rpki.lo: bgpd/bgp_rpki_clippy.c
|
||||
bgpd/bgp_bmp_clippy.c: $(CLIPPY_DEPS)
|
||||
bgpd/bgp_bmp.lo: bgpd/bgp_bmp_clippy.c
|
||||
|
10
configure.ac
10
configure.ac
@ -1563,12 +1563,10 @@ dnl ##########################################################################
|
||||
dnl ------------------
|
||||
dnl check C-Ares library
|
||||
dnl ------------------
|
||||
if test "${NHRPD}" != ""; then
|
||||
PKG_CHECK_MODULES([CARES], [libcares], ,[
|
||||
AC_MSG_ERROR([trying to build nhrpd, but libcares not found. install c-ares and its -dev headers.])
|
||||
])
|
||||
fi
|
||||
AM_CONDITIONAL([CARES], [test "${NHRPD}" != ""])
|
||||
PKG_CHECK_MODULES([CARES], [libcares], ,[
|
||||
AC_MSG_ERROR([libcares not found. install c-ares and its -dev headers.])
|
||||
])
|
||||
AM_CONDITIONAL([CARES], [true])
|
||||
|
||||
dnl ------------------
|
||||
dnl check Net-SNMP library
|
||||
|
1
debian/frr.install
vendored
1
debian/frr.install
vendored
@ -10,6 +10,7 @@ usr/lib/frr/watchfrr
|
||||
usr/lib/frr/zebra
|
||||
usr/lib/*/frr/modules/zebra_irdp.so
|
||||
usr/lib/*/frr/modules/zebra_fpm.so
|
||||
usr/lib/*/frr/modules/bgpd_bmp.so
|
||||
usr/share/doc/frr/examples
|
||||
usr/share/man/
|
||||
usr/share/yang/
|
||||
|
170
doc/user/bmp.rst
Normal file
170
doc/user/bmp.rst
Normal file
@ -0,0 +1,170 @@
|
||||
.. _bmp:
|
||||
|
||||
***
|
||||
BMP
|
||||
***
|
||||
|
||||
:abbr:`BMP` (BGP Monitoring Protocol, :rfc:`7854`) is used to send monitoring
|
||||
data from BGP routers to network management entities.
|
||||
|
||||
Implementation characteristics
|
||||
==============================
|
||||
|
||||
The `BMP` implementation in FRR has the following properties:
|
||||
|
||||
- only the :rfc:`7854` features are currently implemented. This means protocol
|
||||
version 3 without any extensions. It is not possible to use an older draft
|
||||
protocol version of BMP.
|
||||
|
||||
- the following statistics codes are implemented:
|
||||
|
||||
- 0: count of prefixes rejected
|
||||
- 2: count of duplicate prefix withdrawals
|
||||
- 3: count of **prefixes** with loop in cluster id
|
||||
- 4: count of **prefixes** with loop in AS-path
|
||||
- 5: count of **prefixes** with loop in originator
|
||||
- 11: count of updates subjected to :rfc:`7607` "treat as withdrawal"
|
||||
handling due to errors
|
||||
- 65531: *experimental* count of prefixes rejected due to invalid next-hop
|
||||
|
||||
Note that stat items 3, 4 and 5 are specified to count updates, but FRR
|
||||
implements them as prefix-based counters.
|
||||
|
||||
- **route mirroring** is fully implemented, however BGP OPEN messages are not
|
||||
currently included in route mirroring messages. Their contents can be
|
||||
extracted from the "peer up" notification for sessions that established
|
||||
successfully. OPEN messages for failed sessions cannot currently be
|
||||
mirrored.
|
||||
|
||||
- **route monitoring** is available for IPv4 and IPv6 AFIs, unicast and
|
||||
multicast SAFIs. Other SAFIs (VPN, Labeled-Unicast, Flowspec, etc.) are not
|
||||
currently supported.
|
||||
|
||||
- monitoring peers that have BGP **add-path** enabled on the session will
|
||||
result in somewhat unpredictable behaviour. Currently, the outcome is:
|
||||
|
||||
- route mirroring functions as intended, messages are copied verbatim
|
||||
- the add-path ID is never included in route monitoring messages
|
||||
- if multiple paths were received from a peer, an unpredictable path is
|
||||
picked and sent on the BMP session. The selection will differ for
|
||||
pre-policy and post-policy monitoring sessions.
|
||||
- as long as any path is present, something will be advertised on BMP
|
||||
sessions. Only after the last path is gone a withdrawal will be sent on
|
||||
BMP sessions.
|
||||
- updates to additional paths will trigger BMP route monitoring messages.
|
||||
There is no guarantee on consistency regarding which path is sent in these
|
||||
messages.
|
||||
|
||||
- monitoring peers with :rfc:`5549` extended next-hops has not been tested.
|
||||
|
||||
Starting BMP
|
||||
============
|
||||
|
||||
BMP is implemented as a loadable module. This means that to use BMP, ``bgpd``
|
||||
must be started with the ``-M bmp`` option. It is not possible to enable BMP
|
||||
if ``bgpd`` was started without this option.
|
||||
|
||||
Configuring BMP
|
||||
===============
|
||||
|
||||
All of FRR's BMP configuration options are located inside the
|
||||
:clicmd:`router bgp ASN` block. Configure BGP first before proceeding to BMP
|
||||
setup.
|
||||
|
||||
There is one option that applies to the BGP instance as a whole:
|
||||
|
||||
.. index:: bmp mirror buffer-limit(0-4294967294)
|
||||
.. clicmd:: [no] bmp mirror buffer-limit(0-4294967294)
|
||||
|
||||
This sets the maximum amount of memory used for buffering BGP messages
|
||||
(updates, keepalives, ...) for sending in BMP Route Mirroring.
|
||||
|
||||
The buffer is for the entire BGP instance; if multiple BMP targets are
|
||||
configured they reference the same buffer and do not consume additional
|
||||
memory. Queue overhead is included in accounting this memory, so the
|
||||
actual space available for BGP messages is slightly less than the value
|
||||
configured here.
|
||||
|
||||
If the buffer fills up, the oldest messages are removed from the buffer and
|
||||
any BMP sessions where the now-removed messages were still pending have
|
||||
their **entire** queue flushed and a "Mirroring Messages Lost" BMP message
|
||||
is sent.
|
||||
|
||||
BMP Route Monitoring is not affected by this option.
|
||||
|
||||
All other configuration is managed per targets:
|
||||
|
||||
.. index:: bmp targets NAME
|
||||
.. clicmd:: [no] bmp targets NAME
|
||||
|
||||
Create/delete a targets group. As implied by the plural name, targets may
|
||||
cover multiple outbound active BMP sessions as well as inbound passive
|
||||
listeners.
|
||||
|
||||
If BMP sessions have the same configuration, putting them in the same
|
||||
``bmp targets`` will reduce overhead.
|
||||
|
||||
BMP session configuration
|
||||
-------------------------
|
||||
|
||||
Inside a ``bmp targets`` block, the following commands control session
|
||||
establishment:
|
||||
|
||||
.. index:: bmp connect HOSTNAME port (1-65535) {min-retry MSEC|max-retry MSEC}
|
||||
.. clicmd:: [no] bmp connect HOSTNAME port (1-65535) {min-retry MSEC|max-retry MSEC}
|
||||
|
||||
Add/remove an active outbound BMP session. HOSTNAME is resolved via DNS,
|
||||
if multiple addresses are returned they are tried in nondeterministic
|
||||
order. Only one connection will be established even if multiple addresses
|
||||
are returned. ``min-retry`` and ``max-retry`` specify (in milliseconds)
|
||||
bounds for exponential backoff.
|
||||
|
||||
.. warning::
|
||||
|
||||
``ip access-list`` and ``ipv6 access-list`` are checked for outbound
|
||||
connections resulting from ``bmp connect`` statements.
|
||||
|
||||
.. index:: bmp listener <X:X::X:X|A.B.C.D> port (1-65535)
|
||||
.. clicmd:: [no] bmp listener <X:X::X:X|A.B.C.D> port (1-65535)
|
||||
|
||||
Accept incoming BMP sessions on the specified address and port. You can
|
||||
use ``0.0.0.0`` and ``::`` to listen on all IPv4/IPv6 addresses.
|
||||
|
||||
.. clicmd:: [no] ip access-list NAME
|
||||
.. clicmd:: [no] ipv6 access-list NAME
|
||||
|
||||
Restrict BMP sessions to the addresses allowed by the respective access
|
||||
lists. The access lists are checked for both passive and active BMP
|
||||
sessions. Changes do not affect currently established sessions.
|
||||
|
||||
BMP data feed configuration
|
||||
---------------------------
|
||||
|
||||
The following commands configure what BMP messages are sent on sessions
|
||||
associated with a particular ``bmp targets``:
|
||||
|
||||
.. index:: bmp stats [interval (100-86400000)]
|
||||
.. clicmd:: [no] bmp stats [interval (100-86400000)]
|
||||
|
||||
Send BMP Statistics (counter) messages at the specified interval (in
|
||||
milliseconds.)
|
||||
|
||||
.. index:: bmp monitor AFI SAFI <pre-policy|post-policy>
|
||||
.. clicmd:: [no] bmp monitor AFI SAFI <pre-policy|post-policy>
|
||||
|
||||
Perform Route Monitoring for the specified AFI and SAFI. Only IPv4 and
|
||||
IPv6 are currently valid for AFI, and only unicast and multicast are valid
|
||||
for SAFI. Other AFI/SAFI combinations may be added in the future.
|
||||
|
||||
All BGP neighbors are included in Route Monitoring. Options to select
|
||||
a subset of BGP sessions may be added in the future.
|
||||
|
||||
.. index:: bmp mirror
|
||||
.. clicmd:: [no] bmp mirror
|
||||
|
||||
Perform Route Mirroring for all BGP neighbors. Since this provides a
|
||||
direct feed of BGP messages, there are no AFI/SAFI options to be
|
||||
configured.
|
||||
|
||||
All BGP neighbors are included in Route Mirroring. Options to select
|
||||
a subset of BGP sessions may be added in the future.
|
@ -57,6 +57,7 @@ Protocols
|
||||
static
|
||||
vnc
|
||||
vrrp
|
||||
bmp
|
||||
|
||||
########
|
||||
Appendix
|
||||
|
@ -7,6 +7,7 @@ user_RSTFILES = \
|
||||
doc/user/ldpd.rst \
|
||||
doc/user/basic.rst \
|
||||
doc/user/bgp.rst \
|
||||
doc/user/bmp.rst \
|
||||
doc/user/bugs.rst \
|
||||
doc/user/conf.py \
|
||||
doc/user/eigrpd.rst \
|
||||
|
@ -151,6 +151,7 @@ const char *node_names[] = {
|
||||
"bfd peer", /* BFD_PEER_NODE */
|
||||
"openfabric", // OPENFABRIC_NODE
|
||||
"vrrp", /* VRRP_NODE */
|
||||
"bmp", /* BMP_NODE */
|
||||
};
|
||||
/* clang-format on */
|
||||
|
||||
@ -975,6 +976,7 @@ enum node_type node_parent(enum node_type node)
|
||||
case BGP_IPV6M_NODE:
|
||||
case BGP_EVPN_NODE:
|
||||
case BGP_IPV6L_NODE:
|
||||
case BMP_NODE:
|
||||
ret = BGP_NODE;
|
||||
break;
|
||||
case BGP_EVPN_VNI_NODE:
|
||||
@ -1491,6 +1493,7 @@ void cmd_exit(struct vty *vty)
|
||||
case BGP_IPV6M_NODE:
|
||||
case BGP_EVPN_NODE:
|
||||
case BGP_IPV6L_NODE:
|
||||
case BMP_NODE:
|
||||
vty->node = BGP_NODE;
|
||||
break;
|
||||
case BGP_EVPN_VNI_NODE:
|
||||
|
@ -159,6 +159,7 @@ enum node_type {
|
||||
BFD_PEER_NODE, /* BFD peer configuration mode. */
|
||||
OPENFABRIC_NODE, /* OpenFabric router configuration node */
|
||||
VRRP_NODE, /* VRRP node */
|
||||
BMP_NODE, /* BMP config under router bgp */
|
||||
NODE_TYPE_MAX, /* maximum */
|
||||
};
|
||||
|
||||
|
@ -351,6 +351,7 @@ if __name__ == '__main__':
|
||||
macros = Macros()
|
||||
macros.load('lib/route_types.h')
|
||||
macros.load(os.path.join(basepath, 'lib/command.h'))
|
||||
macros.load(os.path.join(basepath, 'bgpd/bgp_vty.h'))
|
||||
# sigh :(
|
||||
macros['PROTO_REDIST_STR'] = 'FRR_REDIST_STR_ISISD'
|
||||
|
||||
|
@ -634,6 +634,7 @@ fi
|
||||
%{_libdir}/frr/modules/bgpd_rpki.so
|
||||
%endif
|
||||
%{_libdir}/frr/modules/zebra_irdp.so
|
||||
%{_libdir}/frr/modules/bgpd_bmp.so
|
||||
%{_bindir}/*
|
||||
%config(noreplace) %{configdir}/[!v]*.conf*
|
||||
%config(noreplace) %attr(750,%{frr_user},%{frr_user}) %{configdir}/daemons
|
||||
|
@ -1260,6 +1260,8 @@ static struct cmd_node bgp_vrf_policy_node = {BGP_VRF_POLICY_NODE,
|
||||
static struct cmd_node bgp_vnc_l2_group_node = {
|
||||
BGP_VNC_L2_GROUP_NODE, "%s(config-router-vnc-l2-group)# "};
|
||||
|
||||
static struct cmd_node bmp_node = {BMP_NODE, "%s(config-bgp-bmp)# "};
|
||||
|
||||
static struct cmd_node ospf_node = {OSPF_NODE, "%s(config-router)# "};
|
||||
|
||||
static struct cmd_node eigrp_node = {EIGRP_NODE, "%s(config-router)# "};
|
||||
@ -1335,7 +1337,7 @@ DEFUNSH(VTYSH_REALLYALL, vtysh_end_all, vtysh_end_all_cmd, "end",
|
||||
}
|
||||
|
||||
DEFUNSH(VTYSH_BGPD, router_bgp, router_bgp_cmd,
|
||||
"router bgp [(1-4294967295) [<view|vrf> WORD]]",
|
||||
"router bgp [(1-4294967295)$instasn [<view|vrf> WORD]]",
|
||||
ROUTER_STR BGP_STR AS_STR
|
||||
"BGP view\nBGP VRF\n"
|
||||
"View/VRF name\n")
|
||||
@ -1478,6 +1480,18 @@ DEFUNSH(VTYSH_BGPD,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUNSH(VTYSH_BGPD,
|
||||
bmp_targets,
|
||||
bmp_targets_cmd,
|
||||
"bmp targets BMPTARGETS",
|
||||
"BGP Monitoring Protocol\n"
|
||||
"Create BMP target group\n"
|
||||
"Name of the BMP target group\n")
|
||||
{
|
||||
vty->node = BMP_NODE;
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUNSH(VTYSH_BGPD, address_family_evpn, address_family_evpn_cmd,
|
||||
"address-family <l2vpn evpn>",
|
||||
"Enter Address Family command mode\n"
|
||||
@ -1842,6 +1856,7 @@ static int vtysh_exit(struct vty *vty)
|
||||
case BGP_VNC_DEFAULTS_NODE:
|
||||
case BGP_VNC_NVE_GROUP_NODE:
|
||||
case BGP_VNC_L2_GROUP_NODE:
|
||||
case BMP_NODE:
|
||||
vty->node = BGP_NODE;
|
||||
break;
|
||||
case BGP_EVPN_VNI_NODE:
|
||||
@ -1932,6 +1947,19 @@ DEFUNSH(VTYSH_BGPD, rpki_quit, rpki_quit_cmd, "quit",
|
||||
return rpki_exit(self, vty, argc, argv);
|
||||
}
|
||||
|
||||
DEFUNSH(VTYSH_BGPD, bmp_exit, bmp_exit_cmd, "exit",
|
||||
"Exit current mode and down to previous mode\n")
|
||||
{
|
||||
vtysh_exit(vty);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUNSH(VTYSH_BGPD, bmp_quit, bmp_quit_cmd, "quit",
|
||||
"Exit current mode and down to previous mode\n")
|
||||
{
|
||||
return bmp_exit(self, vty, argc, argv);
|
||||
}
|
||||
|
||||
DEFUNSH(VTYSH_VRF, exit_vrf_config, exit_vrf_config_cmd, "exit-vrf",
|
||||
"Exit from VRF configuration mode\n")
|
||||
{
|
||||
@ -3620,6 +3648,7 @@ void vtysh_init_vty(void)
|
||||
install_node(&openfabric_node, NULL);
|
||||
install_node(&vty_node, NULL);
|
||||
install_node(&rpki_node, NULL);
|
||||
install_node(&bmp_node, NULL);
|
||||
#if HAVE_BFDD > 0
|
||||
install_node(&bfd_node, NULL);
|
||||
install_node(&bfd_peer_node, NULL);
|
||||
@ -3853,6 +3882,11 @@ void vtysh_init_vty(void)
|
||||
install_element(BGP_FLOWSPECV4_NODE, &exit_address_family_cmd);
|
||||
install_element(BGP_FLOWSPECV6_NODE, &exit_address_family_cmd);
|
||||
|
||||
install_element(BGP_NODE, &bmp_targets_cmd);
|
||||
install_element(BMP_NODE, &bmp_exit_cmd);
|
||||
install_element(BMP_NODE, &bmp_quit_cmd);
|
||||
install_element(BMP_NODE, &vtysh_end_all_cmd);
|
||||
|
||||
install_element(CONFIG_NODE, &rpki_cmd);
|
||||
install_element(RPKI_NODE, &rpki_exit_cmd);
|
||||
install_element(RPKI_NODE, &rpki_quit_cmd);
|
||||
|
Loading…
Reference in New Issue
Block a user