#include "bgpd/bgp_pbr.h"
#include "bgpd/bgp_addpath.h"
#include "bgpd/bgp_evpn_private.h"
+#include "bgpd/bgp_evpn_mh.h"
#include "bgpd/bgp_mac.h"
DEFINE_MTYPE_STATIC(BGPD, PEER_TX_SHUTDOWN_MSG, "Peer shutdown message (TX)");
return CHECK_FLAG(bm->options, flag);
}
+/* set the bgp no-rib option during runtime and remove installed routes */
+void bgp_option_norib_set_runtime(void)
+{
+ struct bgp *bgp;
+ struct listnode *node;
+ afi_t afi;
+ safi_t safi;
+
+ if (bgp_option_check(BGP_OPT_NO_FIB))
+ return;
+
+ bgp_option_set(BGP_OPT_NO_FIB);
+
+ zlog_info("Disabled BGP route installation to RIB (Zebra)");
+
+ for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, bgp)) {
+ FOREACH_AFI_SAFI(afi, safi)
+ bgp_zebra_withdraw_table_all_subtypes(bgp, afi, safi);
+ }
+
+ zlog_info("All routes have been withdrawn from RIB (Zebra)");
+}
+
+/* unset the bgp no-rib option during runtime and announce routes to Zebra */
+void bgp_option_norib_unset_runtime(void)
+{
+ struct bgp *bgp;
+ struct listnode *node;
+ afi_t afi;
+ safi_t safi;
+
+ if (!bgp_option_check(BGP_OPT_NO_FIB))
+ return;
+
+ bgp_option_unset(BGP_OPT_NO_FIB);
+
+ zlog_info("Enabled BGP route installation to RIB (Zebra)");
+
+ for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, bgp)) {
+ FOREACH_AFI_SAFI(afi, safi)
+ bgp_zebra_announce_table_all_subtypes(bgp, afi, safi);
+ }
+
+ zlog_info("All routes have been installed in RIB (Zebra)");
+}
+
/* Internal function to set BGP structure configureation flag. */
static void bgp_config_set(struct bgp *bgp, int config)
{
peer->addpath_type[afi][safi] = BGP_ADDPATH_NONE;
}
+ /* set nexthop-unchanged for l2vpn evpn by default */
+ SET_FLAG(peer->af_flags[AFI_L2VPN][SAFI_EVPN],
+ PEER_FLAG_NEXTHOP_UNCHANGED);
+
SET_FLAG(peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
/* Initialize per peer bgp GR FSM */
/* Default TTL set. */
peer->ttl = (peer->sort == BGP_PEER_IBGP) ? MAXTTL : BGP_DEFAULT_TTL;
+ /* Default configured keepalives count for shutdown rtt command */
+ peer->rtt_keepalive_conf = 1;
+
SET_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE);
if (afi && safi) {
/* Password configuration */
if (CHECK_FLAG(peer->flags, PEER_FLAG_PASSWORD)) {
XFREE(MTYPE_PEER_PASSWORD, peer->password);
-
if (!accept_peer && !BGP_PEER_SU_UNSPEC(peer)
- && !CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
+ && !CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)
+ && !CHECK_FLAG(peer->flags, PEER_FLAG_DYNAMIC_NEIGHBOR))
bgp_md5_unset(peer);
}
/* Update passwords for new ranges */
if (group->conf->password)
- bgp_md5_set_prefix(prefix, group->conf->password);
+ bgp_md5_set_prefix(group->bgp, prefix, group->conf->password);
return 0;
}
/* Remove passwords for deleted ranges */
if (group->conf->password)
- bgp_md5_unset_prefix(prefix);
+ bgp_md5_unset_prefix(group->bgp, prefix);
return 0;
}
bgp->gr_info[afi][safi].route_list = list_new();
}
- bgp->v_update_delay = BGP_UPDATE_DELAY_DEF;
+ bgp->v_update_delay = bm->v_update_delay;
+ bgp->v_establish_wait = bm->v_establish_wait;
bgp->default_local_pref = BGP_DEFAULT_LOCAL_PREF;
bgp->default_subgroup_pkt_queue_max =
BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX;
static const struct peer_flag_action peer_flag_action_list[] = {
{PEER_FLAG_PASSIVE, 0, peer_change_reset},
{PEER_FLAG_SHUTDOWN, 0, peer_change_reset},
+ {PEER_FLAG_RTT_SHUTDOWN, 0, peer_change_none},
{PEER_FLAG_DONT_CAPABILITY, 0, peer_change_none},
{PEER_FLAG_OVERRIDE_CAPABILITY, 0, peer_change_none},
{PEER_FLAG_STRICT_CAP_MATCH, 0, peer_change_none},
{PEER_FLAG_ORF_PREFIX_RM, 1, peer_change_reset},
{PEER_FLAG_MAX_PREFIX, 0, peer_change_none},
{PEER_FLAG_MAX_PREFIX_WARNING, 0, peer_change_none},
+ {PEER_FLAG_MAX_PREFIX_FORCE, 0, peer_change_none},
{PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED, 0, peer_change_reset_out},
{PEER_FLAG_FORCE_NEXTHOP_SELF, 1, peer_change_reset_out},
{PEER_FLAG_REMOVE_PRIVATE_AS_ALL, 1, peer_change_reset_out},
peer_nsf_stop(peer);
UNSET_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
+
if (peer->t_pmax_restart) {
BGP_TIMER_OFF(peer->t_pmax_restart);
if (bgp_debug_neighbor_events(peer))
peer->host);
}
- if (CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT))
- peer_nsf_stop(peer);
-
if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) {
char *msg = peer->tx_shutdown_message;
size_t msglen;
bgp_session_reset(peer);
}
+/* Enable global administrative shutdown of all peers of BGP instance */
+void bgp_shutdown_enable(struct bgp *bgp, const char *msg)
+{
+ struct peer *peer;
+ struct listnode *node;
+
+ /* do nothing if already shut down */
+ if (CHECK_FLAG(bgp->flags, BGP_FLAG_SHUTDOWN))
+ return;
+
+ /* informational log message */
+ zlog_info("Enabled administrative shutdown on BGP instance AS %u",
+ bgp->as);
+
+ /* iterate through peers of BGP instance */
+ for (ALL_LIST_ELEMENTS_RO(bgp->peer, node, peer)) {
+ /* continue, if peer is already in administrative shutdown. */
+ if (CHECK_FLAG(peer->flags, PEER_FLAG_SHUTDOWN))
+ continue;
+
+ /* send a RFC 4486 notification message if necessary */
+ if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) {
+ if (msg)
+ bgp_notify_send_with_data(
+ peer, BGP_NOTIFY_CEASE,
+ BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN,
+ (uint8_t *)(msg), strlen(msg));
+ else
+ bgp_notify_send(
+ peer, BGP_NOTIFY_CEASE,
+ BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN);
+ }
+
+ /* reset start timer to initial value */
+ peer->v_start = BGP_INIT_START_TIMER;
+
+ /* trigger a RFC 4271 ManualStop event */
+ BGP_EVENT_ADD(peer, BGP_Stop);
+ }
+
+ /* set the BGP instances shutdown flag */
+ SET_FLAG(bgp->flags, BGP_FLAG_SHUTDOWN);
+}
+
+/* Disable global administrative shutdown of all peers of BGP instance */
+void bgp_shutdown_disable(struct bgp *bgp)
+{
+ /* do nothing if not shut down. */
+ if (!CHECK_FLAG(bgp->flags, BGP_FLAG_SHUTDOWN))
+ return;
+
+ /* informational log message */
+ zlog_info("Disabled administrative shutdown on BGP instance AS %u",
+ bgp->as);
+
+ /* clear the BGP instances shutdown flag */
+ UNSET_FLAG(bgp->flags, BGP_FLAG_SHUTDOWN);
+}
+
/* Change specified peer flag. */
static int peer_flag_modify(struct peer *peer, uint32_t flag, int set)
{
peer->ttl = ttl;
if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
- if (peer->fd >= 0 && peer->sort != BGP_PEER_IBGP) {
+ if (peer->sort != BGP_PEER_IBGP) {
if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
bgp_notify_send(peer, BGP_NOTIFY_CEASE,
BGP_NOTIFY_CEASE_CONFIG_CHANGE);
struct prefix *lr;
for (ALL_LIST_ELEMENTS_RO(peer->group->listen_range[AFI_IP], ln, lr))
- bgp_md5_set_prefix(lr, password);
+ bgp_md5_set_prefix(peer->bgp, lr, password);
for (ALL_LIST_ELEMENTS_RO(peer->group->listen_range[AFI_IP6], ln, lr))
- bgp_md5_set_prefix(lr, password);
+ bgp_md5_set_prefix(peer->bgp, lr, password);
return ret;
}
/* Attempt to uninstall password on socket. */
if (!BGP_PEER_SU_UNSPEC(peer))
bgp_md5_unset(peer);
-
/* Skip peer-group mechanics for regular peers. */
return 0;
}
struct prefix *lr;
for (ALL_LIST_ELEMENTS_RO(peer->group->listen_range[AFI_IP], ln, lr))
- bgp_md5_unset_prefix(lr);
+ bgp_md5_unset_prefix(peer->bgp, lr);
for (ALL_LIST_ELEMENTS_RO(peer->group->listen_range[AFI_IP6], ln, lr))
- bgp_md5_unset_prefix(lr);
+ bgp_md5_unset_prefix(peer->bgp, lr);
return 0;
}
int peer_maximum_prefix_set(struct peer *peer, afi_t afi, safi_t safi,
uint32_t max, uint8_t threshold, int warning,
- uint16_t restart)
+ uint16_t restart, bool force)
{
struct peer *member;
struct listnode *node, *nnode;
/* Set flags and configuration on peer. */
peer_af_flag_set(peer, afi, safi, PEER_FLAG_MAX_PREFIX);
+
+ if (force)
+ peer_af_flag_set(peer, afi, safi, PEER_FLAG_MAX_PREFIX_FORCE);
+ else
+ peer_af_flag_unset(peer, afi, safi, PEER_FLAG_MAX_PREFIX_FORCE);
+
if (warning)
peer_af_flag_set(peer, afi, safi, PEER_FLAG_MAX_PREFIX_WARNING);
else
member->pmax[afi][safi] = max;
member->pmax_threshold[afi][safi] = threshold;
member->pmax_restart[afi][safi] = restart;
+
+ if (force)
+ SET_FLAG(member->af_flags[afi][safi],
+ PEER_FLAG_MAX_PREFIX_FORCE);
+ else
+ UNSET_FLAG(member->af_flags[afi][safi],
+ PEER_FLAG_MAX_PREFIX_FORCE);
+
if (warning)
SET_FLAG(member->af_flags[afi][safi],
PEER_FLAG_MAX_PREFIX_WARNING);
/* Inherit configuration from peer-group if peer is member. */
if (peer_group_active(peer)) {
peer_af_flag_inherit(peer, afi, safi, PEER_FLAG_MAX_PREFIX);
+ peer_af_flag_inherit(peer, afi, safi,
+ PEER_FLAG_MAX_PREFIX_FORCE);
peer_af_flag_inherit(peer, afi, safi,
PEER_FLAG_MAX_PREFIX_WARNING);
PEER_ATTR_INHERIT(peer, peer->group, pmax[afi][safi]);
/* Remove flags and configuration from peer. */
peer_af_flag_unset(peer, afi, safi, PEER_FLAG_MAX_PREFIX);
+ peer_af_flag_unset(peer, afi, safi, PEER_FLAG_MAX_PREFIX_FORCE);
peer_af_flag_unset(peer, afi, safi, PEER_FLAG_MAX_PREFIX_WARNING);
peer->pmax[afi][safi] = 0;
peer->pmax_threshold[afi][safi] = 0;
*/
UNSET_FLAG(member->af_flags[afi][safi],
PEER_FLAG_MAX_PREFIX);
+ UNSET_FLAG(member->af_flags[afi][safi],
+ PEER_FLAG_MAX_PREFIX_FORCE);
UNSET_FLAG(member->af_flags[afi][safi],
PEER_FLAG_MAX_PREFIX_WARNING);
member->pmax[afi][safi] = 0;
*/
int peer_clear(struct peer *peer, struct listnode **nnode)
{
- if (!CHECK_FLAG(peer->flags, PEER_FLAG_SHUTDOWN)) {
+ if (!CHECK_FLAG(peer->flags, PEER_FLAG_SHUTDOWN)
+ || !CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHUTDOWN)) {
if (CHECK_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW)) {
UNSET_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
if (peer->t_pmax_restart) {
bm->start_time = bgp_clock();
bm->t_rmap_update = NULL;
bm->rmap_update_timer = RMAP_DEFAULT_UPDATE_TIMER;
+ bm->v_update_delay = BGP_UPDATE_DELAY_DEF;
+ bm->v_establish_wait = BGP_UPDATE_DELAY_DEF;
bm->terminating = false;
bm->socket_buffer = buffer_size;
/* mpls label dynamic allocation pool */
bgp_lp_init(bm->master, &bm->labelpool);
+ bgp_evpn_mh_init();
QOBJ_REG(bm, bgp_master);
}
BGP_TIMER_OFF(bm->t_rmap_update);
bgp_mac_finish();
+ bgp_evpn_mh_finish();
}
struct peer *peer_lookup_in_view(struct vty *vty, struct bgp *bgp,