]> git.proxmox.com Git - mirror_frr.git/blobdiff - bgpd/bgpd.c
Merge pull request #3253 from opensourcerouting/6.0-backport-build
[mirror_frr.git] / bgpd / bgpd.c
index c216d0a56d2821e26bdb29c6bd19d1a714fa350a..7ff5053ce37a8907e65c299acdb1aea15847b981 100644 (file)
@@ -52,6 +52,7 @@
 #include "bgpd/bgp_route.h"
 #include "bgpd/bgp_dump.h"
 #include "bgpd/bgp_debug.h"
+#include "bgpd/bgp_errors.h"
 #include "bgpd/bgp_community.h"
 #include "bgpd/bgp_attr.h"
 #include "bgpd/bgp_regex.h"
@@ -683,12 +684,6 @@ struct peer_af *peer_af_create(struct peer *peer, afi_t afi, safi_t safi)
        /* Allocate new peer af */
        af = XCALLOC(MTYPE_BGP_PEER_AF, sizeof(struct peer_af));
 
-       if (af == NULL) {
-               zlog_err("Could not create af structure for peer %s",
-                        peer->host);
-               return NULL;
-       }
-
        peer->peer_af_array[afid] = af;
        af->afi = afi;
        af->safi = safi;
@@ -888,129 +883,6 @@ static bool peergroup_filter_check(struct peer *peer, afi_t afi, safi_t safi,
        }
 }
 
-/* Reset all address family specific configuration.  */
-static void peer_af_flag_reset(struct peer *peer, afi_t afi, safi_t safi)
-{
-       int i;
-       struct bgp_filter *filter;
-       char orf_name[BUFSIZ];
-
-       filter = &peer->filter[afi][safi];
-
-       /* Clear neighbor filter and route-map */
-       for (i = FILTER_IN; i < FILTER_MAX; i++) {
-               if (filter->dlist[i].name) {
-                       XFREE(MTYPE_BGP_FILTER_NAME, filter->dlist[i].name);
-                       filter->dlist[i].name = NULL;
-               }
-               if (filter->plist[i].name) {
-                       XFREE(MTYPE_BGP_FILTER_NAME, filter->plist[i].name);
-                       filter->plist[i].name = NULL;
-               }
-               if (filter->aslist[i].name) {
-                       XFREE(MTYPE_BGP_FILTER_NAME, filter->aslist[i].name);
-                       filter->aslist[i].name = NULL;
-               }
-       }
-       for (i = RMAP_IN; i < RMAP_MAX; i++) {
-               if (filter->map[i].name) {
-                       XFREE(MTYPE_BGP_FILTER_NAME, filter->map[i].name);
-                       filter->map[i].name = NULL;
-               }
-       }
-
-       /* Clear unsuppress map.  */
-       if (filter->usmap.name)
-               XFREE(MTYPE_BGP_FILTER_NAME, filter->usmap.name);
-       filter->usmap.name = NULL;
-       filter->usmap.map = NULL;
-
-       /* Clear neighbor's all address family flags.  */
-       peer->af_flags[afi][safi] = 0;
-
-       /* Clear neighbor's all address family sflags. */
-       peer->af_sflags[afi][safi] = 0;
-
-       /* Clear neighbor's all address family capabilities. */
-       peer->af_cap[afi][safi] = 0;
-
-       /* Clear ORF info */
-       peer->orf_plist[afi][safi] = NULL;
-       sprintf(orf_name, "%s.%d.%d", peer->host, afi, safi);
-       prefix_bgp_orf_remove_all(afi, orf_name);
-
-       /* Set default neighbor send-community.  */
-       if (!bgp_option_check(BGP_OPT_CONFIG_CISCO)) {
-               SET_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SEND_COMMUNITY);
-               SET_FLAG(peer->af_flags[afi][safi],
-                        PEER_FLAG_SEND_EXT_COMMUNITY);
-               SET_FLAG(peer->af_flags[afi][safi],
-                        PEER_FLAG_SEND_LARGE_COMMUNITY);
-
-               SET_FLAG(peer->af_flags_invert[afi][safi],
-                        PEER_FLAG_SEND_COMMUNITY);
-               SET_FLAG(peer->af_flags_invert[afi][safi],
-                        PEER_FLAG_SEND_EXT_COMMUNITY);
-               SET_FLAG(peer->af_flags_invert[afi][safi],
-                        PEER_FLAG_SEND_LARGE_COMMUNITY);
-       }
-
-       /* Clear neighbor default_originate_rmap */
-       if (peer->default_rmap[afi][safi].name)
-               XFREE(MTYPE_ROUTE_MAP_NAME, peer->default_rmap[afi][safi].name);
-       peer->default_rmap[afi][safi].name = NULL;
-       peer->default_rmap[afi][safi].map = NULL;
-
-       /* Clear neighbor maximum-prefix */
-       peer->pmax[afi][safi] = 0;
-       peer->pmax_threshold[afi][safi] = MAXIMUM_PREFIX_THRESHOLD_DEFAULT;
-}
-
-/* peer global config reset */
-static void peer_global_config_reset(struct peer *peer)
-{
-       int saved_flags = 0;
-
-       peer->change_local_as = 0;
-       peer->ttl = (peer_sort(peer) == BGP_PEER_IBGP ? MAXTTL : 1);
-       if (peer->update_source) {
-               sockunion_free(peer->update_source);
-               peer->update_source = NULL;
-       }
-       if (peer->update_if) {
-               XFREE(MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
-               peer->update_if = NULL;
-       }
-
-       if (peer_sort(peer) == BGP_PEER_IBGP)
-               peer->v_routeadv = BGP_DEFAULT_IBGP_ROUTEADV;
-       else
-               peer->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV;
-
-       /* These are per-peer specific flags and so we must preserve them */
-       saved_flags |= CHECK_FLAG(peer->flags, PEER_FLAG_IFPEER_V6ONLY);
-       saved_flags |= CHECK_FLAG(peer->flags, PEER_FLAG_SHUTDOWN);
-       peer->flags = 0;
-       SET_FLAG(peer->flags, saved_flags);
-
-       peer->holdtime = 0;
-       peer->keepalive = 0;
-       peer->connect = 0;
-       peer->v_connect = BGP_DEFAULT_CONNECT_RETRY;
-
-       /* Reset some other configs back to defaults. */
-       peer->v_start = BGP_INIT_START_TIMER;
-       peer->password = NULL;
-       peer->local_id = peer->bgp->router_id;
-       peer->v_holdtime = peer->bgp->default_holdtime;
-       peer->v_keepalive = peer->bgp->default_keepalive;
-
-       bfd_info_free(&(peer->bfd_info));
-
-       /* Set back the CONFIG_NODE flag. */
-       SET_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE);
-}
-
 /* Check peer's AS number and determines if this peer is IBGP or EBGP */
 static inline bgp_peer_sort_t peer_calc_sort(struct peer *peer)
 {
@@ -1026,9 +898,11 @@ static inline bgp_peer_sort_t peer_calc_sort(struct peer *peer)
                else if (peer->as_type == AS_EXTERNAL)
                        return BGP_PEER_EBGP;
 
-               else if (peer->as_type == AS_SPECIFIED && peer->as)
+               else if (peer->as_type == AS_SPECIFIED && peer->as) {
+                       assert(bgp);
                        return (bgp->as == peer->as ? BGP_PEER_IBGP
                                                    : BGP_PEER_EBGP);
+               }
 
                else {
                        struct peer *peer1;
@@ -1930,8 +1804,8 @@ static int peer_activate_af(struct peer *peer, afi_t afi, safi_t safi)
        int active;
 
        if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
-               zlog_err("%s was called for peer-group %s", __func__,
-                        peer->host);
+               flog_err(BGP_ERR_PEER_GROUP, "%s was called for peer-group %s",
+                         __func__, peer->host);
                return 1;
        }
 
@@ -2044,8 +1918,8 @@ static int non_peergroup_deactivate_af(struct peer *peer, afi_t afi,
                                       safi_t safi)
 {
        if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
-               zlog_err("%s was called for peer-group %s", __func__,
-                        peer->host);
+               flog_err(BGP_ERR_PEER_GROUP, "%s was called for peer-group %s",
+                         __func__, peer->host);
                return 1;
        }
 
@@ -2057,8 +1931,9 @@ static int non_peergroup_deactivate_af(struct peer *peer, afi_t afi,
        peer->afc[afi][safi] = 0;
 
        if (peer_af_delete(peer, afi, safi) != 0) {
-               zlog_err("couldn't delete af structure for peer %s",
-                        peer->host);
+               flog_err(BGP_ERR_PEER_DELETE,
+                         "couldn't delete af structure for peer %s",
+                         peer->host);
                return 1;
        }
 
@@ -2107,8 +1982,9 @@ int peer_deactivate(struct peer *peer, afi_t afi, safi_t safi)
                group = peer->group;
 
                if (peer_af_delete(peer, afi, safi) != 0) {
-                       zlog_err("couldn't delete af structure for peer %s",
-                                peer->host);
+                       flog_err(BGP_ERR_PEER_DELETE,
+                                 "couldn't delete af structure for peer %s",
+                                 peer->host);
                }
 
                for (ALL_LIST_ELEMENTS(group->peer, node, nnode, tmp_peer)) {
@@ -2735,9 +2611,8 @@ int peer_group_bind(struct bgp *bgp, union sockunion *su, struct peer *peer,
                if (peer->group) {
                        assert(group && peer->group == group);
                } else {
-                       struct listnode *pn;
-                       pn = listnode_lookup(bgp->peer, peer);
-                       list_delete_node(bgp->peer, pn);
+                       listnode_delete(bgp->peer, peer);
+
                        peer->group = group;
                        listnode_add_sort(bgp->peer, peer);
 
@@ -2820,61 +2695,6 @@ int peer_group_bind(struct bgp *bgp, union sockunion *su, struct peer *peer,
        return 0;
 }
 
-int peer_group_unbind(struct bgp *bgp, struct peer *peer,
-                     struct peer_group *group)
-{
-       struct peer *other;
-       afi_t afi;
-       safi_t safi;
-
-       if (group != peer->group)
-               return BGP_ERR_PEER_GROUP_MISMATCH;
-
-       FOREACH_AFI_SAFI (afi, safi) {
-               if (peer->afc[afi][safi]) {
-                       peer->afc[afi][safi] = 0;
-                       peer_af_flag_reset(peer, afi, safi);
-
-                       if (peer_af_delete(peer, afi, safi) != 0) {
-                               zlog_err(
-                                       "couldn't delete af structure for peer %s",
-                                       peer->host);
-                       }
-               }
-       }
-
-       assert(listnode_lookup(group->peer, peer));
-       peer_unlock(peer); /* peer group list reference */
-       listnode_delete(group->peer, peer);
-       peer->group = NULL;
-       other = peer->doppelganger;
-
-       if (group->conf->as) {
-               peer_delete(peer);
-               if (other && other->status != Deleted) {
-                       if (other->group) {
-                               peer_unlock(other);
-                               listnode_delete(group->peer, other);
-                       }
-                       other->group = NULL;
-                       peer_delete(other);
-               }
-               return 0;
-       }
-
-       bgp_bfd_deregister_peer(peer);
-       peer_global_config_reset(peer);
-
-       if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) {
-               peer->last_reset = PEER_DOWN_RMAP_UNBIND;
-               bgp_notify_send(peer, BGP_NOTIFY_CEASE,
-                               BGP_NOTIFY_CEASE_CONFIG_CHANGE);
-       } else
-               bgp_session_reset(peer);
-
-       return 0;
-}
-
 static int bgp_startup_timer_expire(struct thread *thread)
 {
        struct bgp *bgp;
@@ -3297,6 +3117,9 @@ int bgp_delete(struct bgp *bgp)
 
        assert(bgp);
        THREAD_OFF(bgp->t_startup);
+       THREAD_OFF(bgp->t_maxmed_onstartup);
+       THREAD_OFF(bgp->t_update_delay);
+       THREAD_OFF(bgp->t_establish_wait);
 
        if (BGP_DEBUG(zebra, ZEBRA)) {
                if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
@@ -3364,15 +3187,16 @@ int bgp_delete(struct bgp *bgp)
                                .import_redirect_rtlist);
                bgp->vpn_policy[afi].import_redirect_rtlist = NULL;
        }
-       /* Remove visibility via the master list - there may however still be
-        * routes to be processed still referencing the struct bgp.
-        */
-       listnode_delete(bm->bgp, bgp);
 
        /* Deregister from Zebra, if needed */
        if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp))
                bgp_zebra_instance_deregister(bgp);
 
+       /* Remove visibility via the master list - there may however still be
+        * routes to be processed still referencing the struct bgp.
+        */
+       listnode_delete(bm->bgp, bgp);
+
        /* Free interfaces in this instance. */
        bgp_if_finish(bgp);
 
@@ -3824,9 +3648,6 @@ struct peer_flag_action {
 
        /* Action when the flag is changed.  */
        enum peer_change_type type;
-
-       /* Peer down cause */
-       uint8_t peer_down;
 };
 
 static const struct peer_flag_action peer_flag_action_list[] = {
@@ -4271,7 +4092,7 @@ static int peer_af_flag_modify(struct peer *peer, afi_t afi, safi_t safi,
                        if (flag & PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS) {
                                if (!bgp_flag_check(
                                            bgp, BGP_FLAG_DETERMINISTIC_MED)) {
-                                       zlog_warn(
+                                       zlog_info(
                                                "%s: enabling bgp deterministic-med, this is required"
                                                " for addpath-tx-bestpath-per-AS",
                                                peer->host);
@@ -6811,17 +6632,6 @@ char *peer_uptime(time_t uptime2, char *buf, size_t len, uint8_t use_json,
        time_t uptime1, epoch_tbuf;
        struct tm *tm;
 
-       /* Check buffer length. */
-       if (len < BGP_UPTIME_LEN) {
-               if (!use_json) {
-                       zlog_warn("peer_uptime (): buffer shortage %lu",
-                                 (unsigned long)len);
-                       /* XXX: should return status instead of buf... */
-                       snprintf(buf, len, "<error> ");
-               }
-               return buf;
-       }
-
        /* If there is no connection has been done before print `never'. */
        if (uptime2 == 0) {
                if (use_json) {
@@ -7536,7 +7346,7 @@ static void bgp_config_write_family(struct vty *vty, struct bgp *bgp, afi_t afi,
 }
 
 /* clang-format off */
-#if defined(VERSION_TYPE_DEV) && CONFDATE > 20180517
+#if CONFDATE > 20190517
 CPP_NOTICE("bgpd: remove 'bgp enforce-first-as' config migration from bgp_config_write")
 #endif
 /* clang-format on */
@@ -7648,10 +7458,6 @@ int bgp_config_write(struct vty *vty)
                        vty_out(vty, " bgp default subgroup-pkt-queue-max %u\n",
                                bgp->default_subgroup_pkt_queue_max);
 
-               /* BGP default autoshutdown neighbors */
-               if (bgp->autoshutdown)
-                       vty_out(vty, " bgp default shutdown\n");
-
                /* BGP client-to-client reflection. */
                if (bgp_flag_check(bgp, BGP_FLAG_NO_CLIENT_TO_CLIENT))
                        vty_out(vty, " no bgp client-to-client reflection\n");
@@ -7805,6 +7611,16 @@ int bgp_config_write(struct vty *vty)
                /* listen range and limit for dynamic BGP neighbors */
                bgp_config_write_listen(vty, bgp);
 
+               /*
+                * BGP default autoshutdown neighbors
+                *
+                * This must be placed after any peer and peer-group
+                * configuration, to avoid setting all peers to shutdown after
+                * a daemon restart, which is undesired behavior. (see #2286)
+                */
+               if (bgp->autoshutdown)
+                       vty_out(vty, " bgp default shutdown\n");
+
                /* No auto-summary */
                if (bgp_option_check(BGP_OPT_CONFIG_CISCO))
                        vty_out(vty, " no auto-summary\n");
@@ -7913,8 +7729,6 @@ static void bgp_if_finish(struct bgp *bgp)
        }
 }
 
-extern void bgp_snmp_init(void);
-
 static void bgp_viewvrf_autocomplete(vector comps, struct cmd_token *token)
 {
        struct vrf *vrf = NULL;