]> git.proxmox.com Git - mirror_frr.git/blobdiff - bgpd/bgpd.c
bgpd: set/unset bgpd no-rib option at runtime
[mirror_frr.git] / bgpd / bgpd.c
index 46cbc7d2e2bb00106f7990876690c55c26aab24b..84d4aeb1e64fdacb0d10b2f1e877af683f137b29 100644 (file)
@@ -202,6 +202,52 @@ int bgp_option_check(int flag)
        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)
 {
@@ -1604,6 +1650,9 @@ struct peer *peer_create(union sockunion *su, const char *conf_if,
        /* 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) {
@@ -2284,9 +2333,9 @@ int peer_delete(struct peer *peer)
        /* 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);
        }
 
@@ -2668,7 +2717,7 @@ int peer_group_listen_range_add(struct peer_group *group, struct prefix *range)
 
        /* 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;
 }
@@ -2715,7 +2764,7 @@ int peer_group_listen_range_del(struct peer_group *group, struct prefix *range)
 
        /* Remove passwords for deleted ranges */
        if (group->conf->password)
-               bgp_md5_unset_prefix(prefix);
+               bgp_md5_unset_prefix(group->bgp, prefix);
 
        return 0;
 }
@@ -2966,7 +3015,8 @@ static struct bgp *bgp_create(as_t *as, const char *name,
                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;
@@ -3865,6 +3915,7 @@ struct peer_flag_action {
 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},
@@ -3967,6 +4018,7 @@ static void peer_flag_modify_action(struct peer *peer, uint32_t flag)
                                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))
@@ -4020,6 +4072,65 @@ static void peer_flag_modify_action(struct peer *peer, uint32_t flag)
                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)
 {
@@ -5562,9 +5673,9 @@ int peer_password_set(struct peer *peer, const char *password)
        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;
 }
@@ -5600,7 +5711,6 @@ int peer_password_unset(struct peer *peer)
                /* 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;
        }
@@ -5635,9 +5745,9 @@ int peer_password_unset(struct peer *peer)
        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;
 }
@@ -6770,7 +6880,8 @@ int peer_ttl_security_hops_unset(struct peer *peer)
  */
 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) {
@@ -6941,6 +7052,8 @@ void bgp_master_init(struct thread_master *master, const int buffer_size)
        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;