]> git.proxmox.com Git - mirror_frr.git/blobdiff - bgpd/bgpd.c
Merge branch 'master' into evpn-symmetric-routing
[mirror_frr.git] / bgpd / bgpd.c
index 8aaf19c7e1e09c5d25c5d8e8c82c2332de2975fc..0947c85fcf31533bc184da4ae6afb1304940b611 100644 (file)
@@ -24,6 +24,7 @@
 #include "thread.h"
 #include "buffer.h"
 #include "stream.h"
+#include "ringbuf.h"
 #include "command.h"
 #include "sockunion.h"
 #include "sockopt.h"
@@ -78,7 +79,7 @@
 #include "bgpd/bgp_evpn_vty.h"
 #include "bgpd/bgp_keepalives.h"
 #include "bgpd/bgp_io.h"
-
+#include "bgpd/bgp_ecommunity.h"
 
 DEFINE_MTYPE_STATIC(BGPD, PEER_TX_SHUTDOWN_MSG, "Peer shutdown message (TX)");
 DEFINE_QOBJ_TYPE(bgp_master)
@@ -217,7 +218,7 @@ static int bgp_router_id_set(struct bgp *bgp, const struct in_addr *id)
                return 0;
 
        /* EVPN uses router id in RD, withdraw them */
-       if (bgp->advertise_all_vni)
+       if (is_evpn_enabled())
                bgp_evpn_handle_router_id_update(bgp, TRUE);
 
        IPV4_ADDR_COPY(&bgp->router_id, id);
@@ -234,7 +235,7 @@ static int bgp_router_id_set(struct bgp *bgp, const struct in_addr *id)
        }
 
        /* EVPN uses router id in RD, update them */
-       if (bgp->advertise_all_vni)
+       if (is_evpn_enabled())
                bgp_evpn_handle_router_id_update(bgp, FALSE);
 
        return 0;
@@ -912,7 +913,7 @@ static void peer_global_config_reset(struct peer *peer)
 }
 
 /* Check peer's AS number and determines if this peer is IBGP or EBGP */
-static bgp_peer_sort_t peer_calc_sort(struct peer *peer)
+static inline bgp_peer_sort_t peer_calc_sort(struct peer *peer)
 {
        struct bgp *bgp;
 
@@ -1162,7 +1163,9 @@ struct peer *peer_new(struct bgp *bgp)
         */
        peer->obuf_work =
                stream_new(BGP_MAX_PACKET_SIZE + BGP_MAX_PACKET_SIZE_OVERFLOW);
-       peer->ibuf_work = stream_new(BGP_MAX_PACKET_SIZE * BGP_READ_PACKET_MAX);
+       peer->ibuf_work =
+               ringbuf_new(BGP_MAX_PACKET_SIZE * BGP_READ_PACKET_MAX);
+
        peer->scratch = stream_new(BGP_MAX_PACKET_SIZE);
 
        bgp_sync_init(peer);
@@ -1204,7 +1207,7 @@ void peer_xfer_config(struct peer *peer_dst, struct peer *peer_src)
        peer_dst->local_as = peer_src->local_as;
        peer_dst->ifindex = peer_src->ifindex;
        peer_dst->port = peer_src->port;
-       peer_sort(peer_dst);
+       (void)peer_sort(peer_dst);
        peer_dst->rmap_type = peer_src->rmap_type;
 
        /* Timers */
@@ -1475,9 +1478,12 @@ struct peer *peer_create(union sockunion *su, const char *conf_if,
        hash_get(bgp->peerhash, peer, hash_alloc_intern);
 
        /* Adjust update-group coalesce timer heuristics for # peers. */
-       long ct = BGP_DEFAULT_SUBGROUP_COALESCE_TIME
-                 + (bgp->peer->count * BGP_PEER_ADJUST_SUBGROUP_COALESCE_TIME);
-       bgp->coalesce_time = MIN(BGP_MAX_SUBGROUP_COALESCE_TIME, ct);
+       if (bgp->heuristic_coalesce) {
+               long ct = BGP_DEFAULT_SUBGROUP_COALESCE_TIME
+                         + (bgp->peer->count
+                            * BGP_PEER_ADJUST_SUBGROUP_COALESCE_TIME);
+               bgp->coalesce_time = MIN(BGP_MAX_SUBGROUP_COALESCE_TIME, ct);
+       }
 
        active = peer_active(peer);
 
@@ -1882,6 +1888,11 @@ static int peer_activate_af(struct peer *peer, afi_t afi, safi_t safi)
                                                BGP_NOTIFY_CEASE_CONFIG_CHANGE);
                        }
                }
+               if (peer->status == OpenSent || peer->status == OpenConfirm) {
+                       peer->last_reset = PEER_DOWN_AF_ACTIVATE;
+                       bgp_notify_send(peer, BGP_NOTIFY_CEASE,
+                                       BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+               }
        }
 
        return 0;
@@ -2171,7 +2182,7 @@ int peer_delete(struct peer *peer)
        }
 
        if (peer->ibuf_work) {
-               stream_free(peer->ibuf_work);
+               ringbuf_del(peer->ibuf_work);
                peer->ibuf_work = NULL;
        }
 
@@ -3134,6 +3145,9 @@ int bgp_delete(struct bgp *bgp)
                                   bgp->name);
        }
 
+       /* unmap from RT list */
+       bgp_evpn_vrf_delete(bgp);
+
        /* Stop timers. */
        if (bgp->t_rmap_def_originate_eval) {
                BGP_TIMER_OFF(bgp->t_rmap_def_originate_eval);
@@ -7072,6 +7086,11 @@ int bgp_config_write(struct vty *vty)
 
        /* BGP configuration. */
        for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
+
+               /* skip all auto created vrf as they dont have user config */
+               if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_AUTO))
+                       continue;
+
                /* Router bgp ASN */
                vty_out(vty, "router bgp %u", bgp->as);
 
@@ -7296,6 +7315,38 @@ int bgp_config_write(struct vty *vty)
                if (bgp_option_check(BGP_OPT_CONFIG_CISCO))
                        vty_out(vty, " no auto-summary\n");
 
+               /* import route-target */
+               if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_IMPORT_RT_CFGD)) {
+                       char *ecom_str;
+                       struct listnode *node, *nnode;
+                       struct ecommunity *ecom;
+
+                       for (ALL_LIST_ELEMENTS(bgp->vrf_import_rtl, node, nnode,
+                                              ecom)) {
+                               ecom_str = ecommunity_ecom2str(
+                                       ecom, ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
+                               vty_out(vty, "   route-target import %s\n",
+                                       ecom_str);
+                               XFREE(MTYPE_ECOMMUNITY_STR, ecom_str);
+                       }
+               }
+
+               /* export route-target */
+               if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_EXPORT_RT_CFGD)) {
+                       char *ecom_str;
+                       struct listnode *node, *nnode;
+                       struct ecommunity *ecom;
+
+                       for (ALL_LIST_ELEMENTS(bgp->vrf_export_rtl, node, nnode,
+                                              ecom)) {
+                               ecom_str = ecommunity_ecom2str(
+                                       ecom, ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
+                               vty_out(vty, "   route-target export %s\n",
+                                       ecom_str);
+                               XFREE(MTYPE_ECOMMUNITY_STR, ecom_str);
+                       }
+               }
+
                /* IPv4 unicast configuration.  */
                bgp_config_write_family(vty, bgp, AFI_IP, SAFI_UNICAST);
 
@@ -7356,6 +7407,13 @@ void bgp_master_init(struct thread_master *master)
 
        bgp_process_queue_init();
 
+       /* init the rd id space.
+          assign 0th index in the bitfield,
+          so that we start with id 1
+        */
+       bf_init(bm->rd_idspace, UINT16_MAX);
+       bf_assign_zero_index(bm->rd_idspace);
+
        /* Enable multiple instances by default. */
        bgp_option_set(BGP_OPT_MULTIPLE_INSTANCE);
 
@@ -7429,7 +7487,15 @@ void bgp_pthreads_run()
        pthread_attr_init(&attr);
        pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
 
+       /*
+        * Please ensure that the io thread is running
+        * by calling bgp_io_running.  The BGP threads
+        * depend on it being running when we start
+        * looking for it.
+        */
        frr_pthread_run(PTHREAD_IO, &attr, NULL);
+       bgp_io_running();
+
        frr_pthread_run(PTHREAD_KEEPALIVES, &attr, NULL);
 }
 
@@ -7512,6 +7578,7 @@ void bgp_terminate(void)
         */
        /* reverse bgp_master_init */
        bgp_close();
+
        if (bm->listen_sockets)
                list_delete_and_null(&bm->listen_sockets);