LCOV - code coverage report
Current view: top level - bgp - bgp_server.cc (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 754 789 95.6 %
Date: 2026-06-08 02:02:55 Functions: 72 75 96.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
       3             :  */
       4             : 
       5             : #include "bgp/bgp_server.h"
       6             : 
       7             : #include <sys/resource.h>
       8             : 
       9             : #include <boost/foreach.hpp>
      10             : #include <boost/tuple/tuple.hpp>
      11             : 
      12             : #include "base/connection_info.h"
      13             : #include "base/misc_utils.h"
      14             : #include "base/task_annotations.h"
      15             : #include "bgp/bgp_condition_listener.h"
      16             : #include "bgp/bgp_factory.h"
      17             : #include "bgp/bgp_lifetime.h"
      18             : #include "bgp/bgp_log.h"
      19             : #include "bgp/bgp_membership.h"
      20             : #include "bgp/bgp_peer.h"
      21             : #include "bgp/bgp_ribout_updates.h"
      22             : #include "bgp/rtarget/rtarget_table.h"
      23             : #include "bgp/bgp_session_manager.h"
      24             : #include "bgp/bgp_update_sender.h"
      25             : #include "bgp/peer_stats.h"
      26             : #include "bgp/routing-instance/iservice_chain_mgr.h"
      27             : #include "bgp/routing-instance/istatic_route_mgr.h"
      28             : #include "bgp/routing-instance/peer_manager.h"
      29             : #include "bgp/routing-instance/routepath_replicator.h"
      30             : #include "bgp/routing-instance/routing_instance.h"
      31             : #include "bgp/routing-instance/rtarget_group_mgr.h"
      32             : #include "bgp/routing-policy/routing_policy.h"
      33             : 
      34             : #include "config-client-mgr/config_client_show_types.h"
      35             : #include "control-node/sandesh/control_node_types.h"
      36             : 
      37             : using boost::system::error_code;
      38             : using boost::tie;
      39             : using process::ConnectionState;
      40             : using std::boolalpha;
      41             : using std::make_pair;
      42             : using std::map;
      43             : using std::noboolalpha;
      44             : using std::sort;
      45             : using std::string;
      46             : 
      47             : // The ConfigUpdater serves as glue between the BgpConfigManager and the
      48             : // BgpServer.
      49             : class BgpServer::ConfigUpdater {
      50             : public:
      51        9742 :     explicit ConfigUpdater(BgpServer *server) : server_(server) {
      52        9742 :         BgpConfigManager::Observers obs;
      53             :         obs.instance = boost::bind(&ConfigUpdater::ProcessInstanceConfig,
      54        9742 :             this, _1, _2);
      55             :         obs.protocol = boost::bind(&ConfigUpdater::ProcessProtocolConfig,
      56        9742 :             this, _1, _2);
      57             :         obs.neighbor = boost::bind(&ConfigUpdater::ProcessNeighborConfig,
      58        9742 :             this, _1, _2);
      59             :         obs.policy = boost::bind(&ConfigUpdater::ProcessRoutingPolicyConfig,
      60        9742 :             this, _1, _2);
      61             :         obs.system= boost::bind(&ConfigUpdater::ProcessGlobalSystemConfig,
      62        9742 :             this, _1, _2);
      63             :         obs.qos = boost::bind(&ConfigUpdater::ProcessGlobalQosConfig,
      64        9742 :             this, _1, _2);
      65        9742 :         server->config_manager()->RegisterObservers(obs);
      66        9742 :     }
      67             : 
      68           9 :     void ProcessGlobalQosConfig(const BgpGlobalQosConfig *qos,
      69             :         BgpConfigManager::EventType event) {
      70           9 :         if (qos->control_dscp() != server_->global_qos()->control_dscp()) {
      71           9 :             server_->global_qos()->set_control_dscp(qos->control_dscp());
      72           9 :             server_->NotifyDSCPUpdate(qos->control_dscp());
      73             :         }
      74           9 :         server_->global_qos()->set_analytics_dscp(qos->analytics_dscp());
      75           9 :     }
      76             : 
      77         857 :     void ProcessGlobalSystemConfig(const BgpGlobalSystemConfig *new_config,
      78             :             BgpConfigManager::EventType event) {
      79         857 :         bool clear_peers = false;
      80             : 
      81         857 :         if (server_->global_config()->gr_enable() != new_config->gr_enable()) {
      82         564 :             server_->global_config()->set_gr_enable(new_config->gr_enable());
      83         564 :             clear_peers = true;
      84             :         }
      85         857 :         if (server_->global_config()->gr_time() != new_config->gr_time()) {
      86         784 :             server_->global_config()->set_gr_time(new_config->gr_time());
      87         784 :             clear_peers = true;
      88             :         }
      89         857 :         if (server_->global_config()->llgr_time() != new_config->llgr_time()) {
      90         784 :             server_->global_config()->set_llgr_time(new_config->llgr_time());
      91         784 :             clear_peers = true;
      92             :         }
      93        1714 :         if (server_->global_config()->end_of_rib_timeout() !=
      94         857 :                 new_config->end_of_rib_timeout()) {
      95        1126 :             server_->global_config()->set_end_of_rib_timeout(
      96         563 :                 new_config->end_of_rib_timeout());
      97         563 :             clear_peers = true;
      98             :         }
      99        1714 :         if (server_->global_config()->gr_bgp_helper() !=
     100         857 :                 new_config->gr_bgp_helper()) {
     101        1122 :             server_->global_config()->set_gr_bgp_helper(
     102         561 :                 new_config->gr_bgp_helper());
     103         561 :             clear_peers = true;
     104             :         }
     105        1714 :         if (server_->global_config()->enable_4byte_as() !=
     106         857 :                 new_config->enable_4byte_as()) {
     107         160 :             server_->global_config()->set_enable_4byte_as(
     108          80 :                 new_config->enable_4byte_as());
     109          80 :             clear_peers = true;
     110             :         }
     111             : 
     112        1714 :         if (server_->global_config()->fc_enabled() !=
     113         857 :                 new_config->fc_enabled()) {
     114          18 :             server_->global_config()->set_fc_enabled(
     115           9 :                 new_config->fc_enabled());
     116           9 :             clear_peers = true;
     117             :         }
     118             : 
     119        1714 :         if (server_->global_config()->nh_check_enabled() !=
     120         857 :                 new_config->nh_check_enabled()) {
     121           4 :             server_->global_config()->set_nh_check_enabled(
     122           2 :                 new_config->nh_check_enabled());
     123           2 :             clear_peers = true;
     124             :         }
     125             : 
     126             :         // Clear peers if there's a change in always-compare-med knob.
     127        1714 :         if (server_->global_config()->always_compare_med() !=
     128         857 :             new_config->always_compare_med()) {
     129          10 :             server_->global_config()->set_always_compare_med(
     130           5 :                 new_config->always_compare_med());
     131           5 :             clear_peers = true;
     132             :         }
     133             : 
     134             :         // Process a change in rd-cluster-seed knob.
     135        1714 :         if (server_->global_config()->rd_cluster_seed() !=
     136         857 :             new_config->rd_cluster_seed()) {
     137          50 :           server_->global_config()->set_rd_cluster_seed(
     138          25 :               new_config->rd_cluster_seed());
     139             :         }
     140             : 
     141             :         // Process a change in xmpp-hold-time knob.
     142        1714 :         if (server_->global_config()->xmpp_hold_time() !=
     143         857 :             new_config->xmpp_hold_time()) {
     144          22 :           server_->global_config()->set_xmpp_hold_time(
     145          11 :               new_config->xmpp_hold_time());
     146             :         }
     147             : 
     148             :         // Process a change in all-tags-are-global knob.
     149        1714 :         if (server_->global_config()->all_tags_are_global() !=
     150         857 :             new_config->all_tags_are_global()) {
     151           8 :           server_->global_config()->set_all_tags_are_global(
     152           4 :               new_config->all_tags_are_global());
     153             :         }
     154             : 
     155         857 :         bool clear_bgpaas_peers = false;
     156             : 
     157             :         // Clear bgpaas peers if there's a change in bgpaas-port-start.
     158        1714 :         if (server_->global_config()->bgpaas_port_start() !=
     159         857 :                 new_config->bgpaas_port_start()) {
     160        1386 :             server_->global_config()->set_bgpaas_port_start(
     161         693 :                 new_config->bgpaas_port_start());
     162         693 :             clear_bgpaas_peers = true;
     163             :         }
     164             : 
     165             :         // Clear bgpaas peers if there's a change in bgpaas-port-end.
     166        1714 :         if (server_->global_config()->bgpaas_port_end() !=
     167         857 :                 new_config->bgpaas_port_end()) {
     168        1386 :             server_->global_config()->set_bgpaas_port_end(
     169         693 :                 new_config->bgpaas_port_end());
     170         693 :             clear_bgpaas_peers = true;
     171             :         }
     172             : 
     173         857 :         if (clear_peers) {
     174         812 :             RoutingInstanceMgr *ri_mgr = server_->routing_instance_mgr();
     175         812 :             RoutingInstance *rti = ri_mgr->GetDefaultRoutingInstance();
     176         812 :             assert(rti);
     177         812 :             PeerManager *peer_manager = rti->LocatePeerManager();
     178         812 :             peer_manager->ClearAllPeers();
     179             :         }
     180             : 
     181         857 :         if (clear_peers || clear_bgpaas_peers)
     182         837 :             server_->ClearBgpaaSPeers();
     183         857 :     }
     184             : 
     185        9049 :     void ProcessProtocolConfig(const BgpProtocolConfig *protocol_config,
     186             :                                BgpConfigManager::EventType event) {
     187        9049 :         const string &instance_name = protocol_config->instance_name();
     188             : 
     189             :         // We only support BGP sessions in master instance for now.
     190        9049 :         if (instance_name != BgpConfigManager::kMasterInstance) {
     191           0 :             return;
     192             :         }
     193             : 
     194        9049 :         if (event == BgpConfigManager::CFG_ADD ||
     195             :             event == BgpConfigManager::CFG_CHANGE) {
     196        7670 :             BgpServerConfigUpdate(instance_name, protocol_config);
     197        1379 :         } else if (event == BgpConfigManager::CFG_DELETE) {
     198        1379 :             BgpServerConfigUpdate(instance_name, NULL);
     199             :         } else {
     200           0 :             assert(false);
     201             :         }
     202             :     }
     203             : 
     204        9049 :     void BgpServerConfigUpdate(string instance_name,
     205             :                                const BgpProtocolConfig *config) {
     206        9049 :         boost::system::error_code ec;
     207        9049 :         uint32_t config_identifier = 0;
     208        9049 :         uint32_t config_autonomous_system = 0;
     209        9049 :         uint32_t config_local_autonomous_system = 0;
     210        9049 :         uint32_t config_hold_time = 0;
     211        9049 :         uint32_t config_cluster_id = 0;
     212        9049 :         bool config_admin_down = false;
     213        9049 :         if (config) {
     214        7670 :             config_admin_down = config->admin_down();
     215        7670 :             config_identifier = config->identifier();
     216        7670 :             config_autonomous_system = config->autonomous_system();
     217        7670 :             config_local_autonomous_system = config->local_autonomous_system();
     218        7670 :             config_cluster_id = config->cluster_id();
     219        7670 :             config_hold_time = config->hold_time();
     220             :         }
     221             : 
     222        9049 :         if (server_->admin_down_ != config_admin_down) {
     223          44 :             if (server_->admin_down_) {
     224          18 :                 BGP_LOG_STR(BgpConfig, SandeshLevel::SYS_DEBUG,
     225             :                             BGP_LOG_FLAG_SYSLOG, "Updated Admin Down from " <<
     226             :                             boolalpha << server_->admin_down_ << noboolalpha <<
     227             :                             " to " <<
     228             :                             boolalpha << config_admin_down << noboolalpha);
     229             :             } else {
     230          26 :                 BGP_LOG_NOTICE_STR(BgpConfig, BGP_LOG_FLAG_SYSLOG,
     231             :                             "Updated Admin Down from " <<
     232             :                             boolalpha << server_->admin_down_ << noboolalpha <<
     233             :                             " to " <<
     234             :                             boolalpha << config_admin_down << noboolalpha);
     235             :             }
     236          44 :             server_->admin_down_ = config_admin_down;
     237          44 :             if (server_->admin_down_)
     238          26 :                 server_->NotifyAdminDown();
     239             :         }
     240             : 
     241             :         // We currently do not support bind failures or changes to listen port
     242             :         // in production mode.
     243        9559 :         if (config && !server_->session_manager()->Initialize(config->port()) &&
     244         510 :                 !bgp_log_test::unit_test()) {
     245             :             // Disable core file generation and exit.
     246             :             rlimit new_core_limit;
     247           0 :             new_core_limit.rlim_cur = 0;
     248           0 :             new_core_limit.rlim_max = 0;
     249           0 :             setrlimit(RLIMIT_CORE, &new_core_limit);
     250           0 :             BGP_LOG_WARNING_STR(BgpConfig, BGP_LOG_FLAG_SYSLOG,
     251             :                 "Process exit! due to tcp server port " << config->port() <<
     252             :                 " bind failure");
     253           0 :             if (!bgp_log_test::unit_test())
     254           0 :                 kill(getpid(), SIGTERM);
     255             :         }
     256             : 
     257        9049 :         Ip4Address identifier(ntohl(config_identifier));
     258        9049 :         if (server_->bgp_identifier_ != identifier) {
     259        7330 :             if (!server_->bgp_identifier_.is_unspecified()) {
     260        1431 :                 BGP_LOG_NOTICE_STR(BgpConfig, BGP_LOG_FLAG_SYSLOG,
     261             :                             "Updated Router ID from " <<
     262             :                             server_->bgp_identifier_.to_string() << " to " <<
     263             :                             identifier.to_string());
     264             :             } else {
     265        5899 :                 BGP_LOG_STR(BgpConfig, SandeshLevel::SYS_DEBUG,
     266             :                              BGP_LOG_FLAG_SYSLOG, "Updated Router ID from " <<
     267             :                             server_->bgp_identifier_.to_string() << " to " <<
     268             :                             identifier.to_string());
     269             :             }
     270        7330 :             server_->UpdateBgpIdentifier(identifier);
     271             :         }
     272             : 
     273        9049 :         bool notify_asn_update = false;
     274        9049 :         uint32_t old_asn = server_->autonomous_system_;
     275        9049 :         uint32_t old_local_asn = server_->local_autonomous_system_;
     276        9049 :         server_->autonomous_system_ = config_autonomous_system;
     277        9049 :         if (config_local_autonomous_system) {
     278        1190 :             server_->local_autonomous_system_ = config_local_autonomous_system;
     279             :         } else {
     280        7859 :             server_->local_autonomous_system_ = config_autonomous_system;
     281             :         }
     282             : 
     283        9049 :         if (server_->autonomous_system_ != old_asn) {
     284        7354 :             if (old_asn != 0) {
     285        1455 :                 BGP_LOG_NOTICE_STR(BgpConfig, BGP_LOG_FLAG_SYSLOG,
     286             :                             "Updated Autonomous System from " << old_asn <<
     287             :                             " to " << server_->autonomous_system_);
     288             :             } else {
     289        5899 :                 BGP_LOG_STR(BgpConfig, SandeshLevel::SYS_DEBUG,
     290             :                             BGP_LOG_FLAG_SYSLOG,
     291             :                             "Updated Autonomous System from " << old_asn <<
     292             :                             " to " << server_->autonomous_system_);
     293             :             }
     294        7354 :             notify_asn_update = true;
     295             :         }
     296             : 
     297        9049 :         if (server_->local_autonomous_system_ != old_local_asn) {
     298        7397 :             if (old_local_asn != 0) {
     299        1498 :                 BGP_LOG_NOTICE_STR(BgpConfig, BGP_LOG_FLAG_SYSLOG,
     300             :                             "Updated Local Autonomous System from " <<
     301             :                             old_local_asn << " to " <<
     302             :                             server_->local_autonomous_system_);
     303             :             } else {
     304        5899 :                 BGP_LOG_STR(BgpConfig, SandeshLevel::SYS_DEBUG,
     305             :                             BGP_LOG_FLAG_SYSLOG,
     306             :                             "Updated Local Autonomous System from " <<
     307             :                             old_local_asn << " to " <<
     308             :                             server_->local_autonomous_system_);
     309             :             }
     310        7397 :             notify_asn_update = true;
     311             :         }
     312             : 
     313        9049 :         if (notify_asn_update) {
     314        7397 :             server_->NotifyASNUpdate(old_asn, old_local_asn);
     315             :         }
     316             : 
     317        9049 :         if (server_->hold_time_ != config_hold_time) {
     318         384 :             BGP_LOG_STR(BgpConfig, SandeshLevel::SYS_DEBUG, BGP_LOG_FLAG_SYSLOG,
     319             :                         "Updated Hold Time from " <<
     320             :                         server_->hold_time_ << " to " << config_hold_time);
     321         384 :             server_->hold_time_ = config_hold_time;
     322             :         }
     323             : 
     324        9049 :         if (server_->cluster_id() != config_cluster_id) {
     325           2 :             BGP_LOG_STR(BgpConfig, SandeshLevel::SYS_DEBUG, BGP_LOG_FLAG_SYSLOG,
     326             :                         "Updated Cluster Id from " <<
     327             :                         server_->cluster_id() << " to " << config_cluster_id);
     328           2 :             server_->set_cluster_id(config_cluster_id);
     329           2 :             RoutingInstanceMgr *ri_mgr = server_->routing_instance_mgr();
     330           2 :             RoutingInstance *rti = ri_mgr->GetDefaultRoutingInstance();
     331           2 :             assert(rti);
     332           2 :             PeerManager *peer_manager = rti->LocatePeerManager();
     333           2 :             peer_manager->ClearAllInternalPeers();
     334             :         }
     335             : 
     336        9049 :         ConnectionState::GetInstance()->Update();
     337        9049 :     }
     338             : 
     339       16903 :     void ProcessNeighborConfig(const BgpNeighborConfig *neighbor_config,
     340             :                                BgpConfigManager::EventType event) {
     341       16903 :         string instance_name = neighbor_config->instance_name();
     342       16903 :         RoutingInstanceMgr *ri_mgr = server_->routing_instance_mgr();
     343       16903 :         RoutingInstance *rti = ri_mgr->GetRoutingInstance(instance_name);
     344       16903 :         if (!rti)
     345         113 :             return;
     346             : 
     347       16790 :         if (event == BgpConfigManager::CFG_ADD ||
     348             :             event == BgpConfigManager::CFG_CHANGE) {
     349       10071 :             if (rti->deleted())
     350           6 :                 return;
     351       10065 :             PeerManager *peer_manager = rti->LocatePeerManager();
     352       10065 :             BgpPeer *peer = peer_manager->PeerLocate(server_, neighbor_config);
     353       10065 :             if (peer) {
     354       10059 :                 server_->RemovePeer(peer->endpoint(), peer);
     355       10059 :                 peer->ConfigUpdate(neighbor_config);
     356       10059 :                 server_->InsertPeer(peer->endpoint(), peer);
     357             :             }
     358       16784 :         } else if (event == BgpConfigManager::CFG_DELETE) {
     359        6719 :             PeerManager *peer_manager = rti->peer_manager();
     360        6719 :             if (!peer_manager)
     361           6 :                 return;
     362        6713 :             BgpPeer *peer = peer_manager->TriggerPeerDeletion(neighbor_config);
     363        6713 :             if (peer) {
     364        6711 :                 server_->RemovePeer(peer->endpoint(), peer);
     365             :             }
     366             :         }
     367       16903 :     }
     368             : 
     369         452 :     void ProcessRoutingPolicyConfig(const BgpRoutingPolicyConfig *policy_config,
     370             :                                     BgpConfigManager::EventType event) {
     371         452 :         RoutingPolicyMgr *mgr = server_->routing_policy_mgr();
     372         452 :         if (event == BgpConfigManager::CFG_ADD) {
     373         161 :             mgr->CreateRoutingPolicy(policy_config);
     374         291 :         } else if (event == BgpConfigManager::CFG_CHANGE) {
     375         248 :             mgr->UpdateRoutingPolicy(policy_config);
     376          43 :         } else if (event == BgpConfigManager::CFG_DELETE) {
     377          43 :             mgr->DeleteRoutingPolicy(policy_config->name());
     378             :         }
     379         452 :     }
     380             : 
     381      160755 :     void ProcessInstanceConfig(const BgpInstanceConfig *instance_config,
     382             :                                BgpConfigManager::EventType event) {
     383      160755 :         RoutingInstanceMgr *mgr = server_->routing_instance_mgr();
     384      160755 :         if (event == BgpConfigManager::CFG_ADD ||
     385             :             event == BgpConfigManager::CFG_CHANGE) {
     386      150434 :             mgr->LocateRoutingInstance(instance_config->name());
     387       10321 :         } else if (event == BgpConfigManager::CFG_DELETE) {
     388       10321 :             mgr->DeleteRoutingInstance(instance_config->name());
     389             :         }
     390      160755 :     }
     391             : 
     392             : private:
     393             :     BgpServer *server_;
     394             : };
     395             : 
     396             : class BgpServer::DeleteActor : public LifetimeActor {
     397             : public:
     398        9742 :     explicit DeleteActor(BgpServer *server)
     399        9742 :         : LifetimeActor(server->lifetime_manager()), server_(server) {
     400        9742 :     }
     401        9638 :     virtual bool MayDelete() const {
     402        9638 :         CHECK_CONCURRENCY("bgp::Config");
     403        9638 :         return server_->session_manager()->MayDelete();
     404             :     }
     405        9638 :     virtual void Shutdown() {
     406        9638 :         CHECK_CONCURRENCY("bgp::Config");
     407        9638 :         server_->session_manager()->Shutdown();
     408        9638 :     }
     409        9638 :     virtual void Destroy() {
     410        9638 :         CHECK_CONCURRENCY("bgp::Config");
     411        9638 :         server_->config_manager()->Terminate();
     412        9638 :         server_->session_manager()->Terminate();
     413        9638 :         TcpServerManager::DeleteServer(server_->session_manager());
     414        9638 :         server_->session_mgr_ = NULL;
     415        9638 :         server_->set_destroyed();
     416        9638 :     }
     417             : 
     418             : private:
     419             :     BgpServer *server_;
     420             : };
     421             : 
     422       27061 : bool BgpServer::IsDeleted() const {
     423       27061 :     return deleter_->IsDeleted();
     424             : }
     425             : 
     426           0 : void BgpServer::RetryDelete() {
     427           0 :     if (!deleter_->IsDeleted())
     428           0 :         return;
     429           0 :     deleter_->RetryDelete();
     430             : }
     431             : 
     432     2146586 : bool BgpServer::IsReadyForDeletion() {
     433     2146586 :     CHECK_CONCURRENCY("bgp::Config");
     434             : 
     435     2146586 :     static TaskScheduler *scheduler = TaskScheduler::GetInstance();
     436     2146586 :     static int db_table_task_id = scheduler->GetTaskId("db::DBTable");
     437             :     static int resolver_path_task_id =
     438     2146586 :         scheduler->GetTaskId("bgp::ResolverPath");
     439             :     static int resolver_nexthop_task_id =
     440     2146586 :         scheduler->GetTaskId("bgp::ResolverNexthop");
     441             : 
     442             :     // Check if any PathResolver is active.
     443             :     // Need to ensure that there's no pending deletes of BgpPaths added by
     444             :     // PathResolver since they hold pointers to IPeer.
     445     3862235 :     if (!scheduler->IsTaskGroupEmpty(resolver_path_task_id) ||
     446     1715649 :         !scheduler->IsTaskGroupEmpty(resolver_nexthop_task_id)) {
     447      430937 :         return false;
     448             :     }
     449             : 
     450             :     // Check if the membership manager queue is empty.
     451     1715649 :     if (!membership_mgr_->IsQueueEmpty()) {
     452       49226 :         return false;
     453             :     }
     454             : 
     455             :     // Check if the Service Chain Manager Work Queues are empty.
     456     1666423 :     if (!inet_service_chain_mgr_->IsQueueEmpty() ||
     457     1666086 :         !inet6_service_chain_mgr_->IsQueueEmpty() ||
     458     4998303 :         !evpn_service_chain_mgr_->IsQueueEmpty() ||
     459     1665794 :         !evpn6_service_chain_mgr_->IsQueueEmpty()) {
     460         629 :         return false;
     461             :     }
     462             : 
     463             :     // Check if the DB requests queue and change list is empty.
     464     1665794 :     if (!db_.IsDBQueueEmpty()) {
     465      120969 :         return false;
     466             :     }
     467             : 
     468             :     // Check if the RTargetGroupManager has processed all RTargetRoute updates.
     469             :     // This is done to ensure that the InterestedPeerList of RtargetGroup gets
     470             :     // updated before allowing the peer to get deleted.
     471     1544825 :     if (!rtarget_group_mgr_->IsRTargetRoutesProcessed()) {
     472        1232 :         return false;
     473             :     }
     474             : 
     475             :     // Check if any db::DBTable task is active.
     476             :     // Need to ensure that there's no pending deletes of BgpPaths added by
     477             :     // the Evpn aliasing module since they hold pointers to IPeer.
     478     1543593 :     if (!scheduler->IsTaskGroupEmpty(db_table_task_id)) {
     479       44849 :         return false;
     480             :     }
     481             : 
     482     1498744 :     return true;
     483             : }
     484             : 
     485        9742 : BgpServer::BgpServer(EventManager *evm)
     486        9742 :     : admin_down_(false),
     487        9742 :       cluster_id_(0),
     488        9742 :       autonomous_system_(0),
     489        9742 :       local_autonomous_system_(0),
     490        9742 :       bgp_identifier_(0),
     491        9742 :       bgp_identifier_u32_(0),
     492        9742 :       hold_time_(0),
     493        9742 :       gr_helper_disable_(false),
     494        9742 :       lifetime_manager_(BgpStaticObjectFactory::Create<BgpLifetimeManager>(this,
     495             :           TaskScheduler::GetInstance()->GetTaskId("bgp::Config"))),
     496        9742 :       deleter_(new DeleteActor(this)),
     497        9742 :       destroyed_(false),
     498        9742 :       logging_disabled_(false),
     499        9742 :       mvpn_ipv4_enable_(false),
     500        9742 :       ignore_aspath_(false),
     501        9742 :       aspath_db_(new AsPathDB(this)),
     502        9742 :       aspath_4byte_db_(new AsPath4ByteDB(this)),
     503        9742 :       as4path_db_(new As4PathDB(this)),
     504        9742 :       olist_db_(new BgpOListDB(this)),
     505        9742 :       cluster_list_db_(new ClusterListDB(this)),
     506        9742 :       comm_db_(new CommunityDB(this)),
     507        9742 :       edge_discovery_db_(new EdgeDiscoveryDB(this)),
     508        9742 :       edge_forwarding_db_(new EdgeForwardingDB(this)),
     509        9742 :       extcomm_db_(new ExtCommunityDB(this)),
     510        9742 :       largecomm_db_(new LargeCommunityDB(this)),
     511        9742 :       ovnpath_db_(new OriginVnPathDB(this)),
     512        9742 :       pmsi_tunnel_db_(new PmsiTunnelDB(this)),
     513        9742 :       attr_db_(new BgpAttrDB(this)),
     514        9742 :       session_mgr_(BgpStaticObjectFactory::Create<BgpSessionManager>(evm, this)),
     515        9742 :       update_sender_(new BgpUpdateSender(this)),
     516        9742 :       inst_mgr_(BgpStaticObjectFactory::Create<RoutingInstanceMgr>(this)),
     517        9742 :       policy_mgr_(BgpStaticObjectFactory::Create<RoutingPolicyMgr>(this)),
     518        9742 :       rtarget_group_mgr_(BgpStaticObjectFactory::Create<RTargetGroupMgr>(this)),
     519        9742 :       membership_mgr_(BgpStaticObjectFactory::Create<BgpMembershipManager>(this)),
     520        9742 :       inet_condition_listener_(new BgpConditionListener(this)),
     521        9742 :       inet6_condition_listener_(new BgpConditionListener(this)),
     522        9742 :       evpn_condition_listener_(new BgpConditionListener(this)),
     523        9742 :       evpn6_condition_listener_(new BgpConditionListener(this)),
     524        9742 :       inetvpn_replicator_(new RoutePathReplicator(this, Address::INETVPN)),
     525        9742 :       ermvpn_replicator_(new RoutePathReplicator(this, Address::ERMVPN)),
     526        9742 :       mvpn_replicator_(new RoutePathReplicator(this, Address::MVPN)),
     527        9742 :       evpn_replicator_(new RoutePathReplicator(this, Address::EVPN)),
     528        9742 :       inet6vpn_replicator_(new RoutePathReplicator(this, Address::INET6VPN)),
     529        9742 :       inet_service_chain_mgr_(
     530        9742 :           BgpStaticObjectFactory::Create<IServiceChainMgr, SCAddress::INET>(this)),
     531        9742 :       inet6_service_chain_mgr_(
     532        9742 :           BgpStaticObjectFactory::Create<IServiceChainMgr, SCAddress::INET6>(this)),
     533        9742 :       evpn_service_chain_mgr_(
     534        9742 :           BgpStaticObjectFactory::Create<IServiceChainMgr, SCAddress::EVPN>(this)),
     535        9742 :       evpn6_service_chain_mgr_(
     536        9742 :           BgpStaticObjectFactory::Create<IServiceChainMgr, SCAddress::EVPN6>(this)),
     537        9742 :       global_config_(new BgpGlobalSystemConfig()),
     538        9742 :       global_qos_(new BgpGlobalQosConfig()),
     539        9742 :       config_mgr_(BgpStaticObjectFactory::Create<BgpConfigManager>(this)),
     540       29226 :       updater_(new ConfigUpdater(this)) {
     541        9742 :     bgp_count_ = 0;
     542        9742 :     num_up_peer_ = 0;
     543        9742 :     deleting_count_ = 0;
     544        9742 :     bgpaas_count_ = 0;
     545        9742 :     num_up_bgpaas_peer_ = 0;
     546        9742 :     deleting_bgpaas_count_ = 0;
     547        9742 :     message_build_error_ = 0;
     548        9742 : }
     549             : 
     550       11292 : BgpServer::~BgpServer() {
     551        9742 :     assert(deleting_count_ == 0);
     552        9742 :     assert(deleting_bgpaas_count_ == 0);
     553        9742 :     assert(srt_manager_list_.empty());
     554       11292 : }
     555             : 
     556         158 : void BgpServer::Initialize() {
     557         158 :     RibOutUpdates::Initialize();
     558         158 : }
     559             : 
     560          62 : void BgpServer::Terminate() {
     561          62 :     RibOutUpdates::Terminate();
     562          62 : }
     563             : 
     564     6060060 : string BgpServer::ToString() const {
     565     6060060 :     return bgp_identifier_.to_string();
     566             : }
     567             : 
     568        9700 : void BgpServer::Shutdown() {
     569        9700 :     deleter_->Delete();
     570        9700 : }
     571             : 
     572       58452 : LifetimeActor *BgpServer::deleter() {
     573       58452 :     return deleter_.get();
     574             : }
     575             : 
     576        6504 : bool BgpServer::HasSelfConfiguration() const {
     577        6504 :     if (!bgp_identifier_u32())
     578         321 :         return false;
     579        6183 :     if (!local_autonomous_system())
     580           0 :         return false;
     581        6183 :     if (!autonomous_system())
     582           0 :         return false;
     583        6183 :     return true;
     584             : }
     585             : 
     586       10358 : int BgpServer::RegisterPeer(BgpPeer *peer) {
     587       10358 :     CHECK_CONCURRENCY("bgp::Config");
     588             : 
     589       10358 :     if (peer->IsRouterTypeBGPaaS()) {
     590         114 :         bgpaas_count_++;
     591             :     } else {
     592       10244 :         bgp_count_++;
     593             :     }
     594             : 
     595       10358 :     BgpPeerList::iterator loc;
     596             :     bool result;
     597       10358 :     tie(loc, result) = peer_list_.insert(make_pair(peer->peer_name(), peer));
     598       10358 :     assert(result);
     599       10358 :     assert(loc->second == peer);
     600             : 
     601       10358 :     size_t bit = peer_bmap_.find_first();
     602       10358 :     if (bit == peer_bmap_.npos) {
     603        9341 :         bit = peer_bmap_.size();
     604        9341 :         peer_bmap_.resize(bit + 1, true);
     605             :     }
     606       10358 :     peer_bmap_.reset(bit);
     607       10358 :     return bit;
     608             : }
     609             : 
     610        9574 : void BgpServer::UnregisterPeer(BgpPeer *peer) {
     611        9574 :     CHECK_CONCURRENCY("bgp::Config");
     612             : 
     613        9574 :     if (peer->IsRouterTypeBGPaaS()) {
     614         112 :         assert(bgpaas_count_);
     615         112 :         bgpaas_count_--;
     616             :     } else {
     617        9462 :         assert(bgp_count_);
     618        9462 :         bgp_count_--;
     619             :     }
     620             : 
     621        9574 :     BgpPeerList::iterator loc = peer_list_.find(peer->peer_name());
     622        9574 :     assert(loc != peer_list_.end());
     623        9574 :     peer_list_.erase(loc);
     624             : 
     625        9574 :     peer_bmap_.set(peer->GetIndex());
     626       18131 :     for (size_t i = peer_bmap_.size(); i != 0; i--) {
     627       15037 :         if (peer_bmap_[i-1] != true) {
     628        6480 :             if (i != peer_bmap_.size()) {
     629        2030 :                 peer_bmap_.resize(i);
     630             :             }
     631        6480 :             return;
     632             :         }
     633             :     }
     634        3094 :     peer_bmap_.clear();
     635             : }
     636             : 
     637          26 : BgpPeer *BgpServer::FindPeer(const string &name) {
     638          26 :     BgpPeerList::iterator loc = peer_list_.find(name);
     639          26 :     return (loc != peer_list_.end() ? loc->second : NULL);
     640             : }
     641             : 
     642        2870 : BgpPeer *BgpServer::FindNextPeer(const string &name) {
     643        2870 :     BgpPeerList::iterator loc = peer_list_.upper_bound(name);
     644        2870 :     return (loc != peer_list_.end() ? loc->second : NULL);
     645             : }
     646             : 
     647       10170 : void BgpServer::InsertPeer(TcpSession::Endpoint remote, BgpPeer *peer) {
     648       10170 :     if (!remote.port() && remote.address().is_unspecified())
     649        9976 :         return;
     650         194 :     endpoint_peer_list_.insert(make_pair(remote, peer));
     651             : }
     652             : 
     653       16770 : void BgpServer::RemovePeer(TcpSession::Endpoint remote, BgpPeer *peer) {
     654       16770 :     EndpointPeerList::iterator loc = endpoint_peer_list_.lower_bound(remote);
     655       16771 :     while (loc != endpoint_peer_list_.end() && loc->first == remote) {
     656         125 :         if (loc->second == peer) {
     657         124 :             endpoint_peer_list_.erase(loc);
     658         124 :             break;
     659             :         }
     660           1 :         ++loc;
     661             :     }
     662       16770 : }
     663             : 
     664         837 : void BgpServer::ClearBgpaaSPeers() {
     665         837 :     for (auto &i : endpoint_peer_list_) {
     666           0 :         i.second->Clear(BgpProto::Notification::OtherConfigChange);
     667             :     }
     668         837 : }
     669             : 
     670         884 : BgpPeer *BgpServer::FindPeer(TcpSession::Endpoint remote) const {
     671         884 :     EndpointPeerList::const_iterator loc = endpoint_peer_list_.find(remote);
     672         884 :     return (loc == endpoint_peer_list_.end() ? NULL : loc->second);
     673             : }
     674             : 
     675           4 : BgpPeer *BgpServer::FindExactPeer(const BgpPeer *peer) const {
     676             :     EndpointPeerList::const_iterator loc =
     677           4 :         endpoint_peer_list_.lower_bound(peer->endpoint());
     678           6 :     while (loc != endpoint_peer_list_.end() && loc->first == peer->endpoint()) {
     679           6 :         if (loc->second == peer)
     680           4 :             return loc->second;
     681           2 :         ++loc;
     682             :     }
     683           0 :     return NULL;
     684             : }
     685             : 
     686      662028 : const string &BgpServer::localname() const {
     687      662028 :     return config_mgr_->localname();
     688             : }
     689             : 
     690      298355 : boost::asio::io_context *BgpServer::ioservice() {
     691      298355 :     return session_manager()->event_manager()->io_service();
     692             : }
     693             : 
     694           0 : bool BgpServer::IsFastConvergenceEnabled() const {
     695           0 :     return (global_config_->fc_enabled());
     696             : }
     697             : 
     698      644197 : bool BgpServer::IsNextHopCheckEnabled() const {
     699      644197 :     if (!global_config_->fc_enabled())
     700      644050 :         return false;
     701         140 :     return (global_config_->nh_check_enabled());
     702             : }
     703             : 
     704        3915 : uint16_t BgpServer::GetGracefulRestartTime() const {
     705        3915 :     if (!global_config_->gr_enable())
     706           1 :         return 0;
     707        3915 :     return global_config_->gr_time();
     708             : }
     709             : 
     710        7810 : uint32_t BgpServer::GetLongLivedGracefulRestartTime() const {
     711        7810 :     if (!global_config_->gr_enable())
     712           1 :         return 0;
     713        7809 :     return global_config_->llgr_time();
     714             : }
     715             : 
     716           5 : uint16_t BgpServer::GetXmppHoldTime() const {
     717           5 :     if (!global_config_->fc_enabled())
     718           1 :         return XMPP_HOLD_TIME_DEFAULT;
     719           4 :     return global_config_->xmpp_hold_time();
     720             : }
     721             : 
     722       17168 : uint32_t BgpServer::GetEndOfRibReceiveTime() const {
     723       17168 :     return global_config_->end_of_rib_timeout();
     724             : }
     725             : 
     726        9854 : uint32_t BgpServer::GetEndOfRibSendTime() const {
     727        9854 :     return global_config_->end_of_rib_timeout();
     728             : }
     729             : 
     730        9453 : bool BgpServer::IsServerStartingUp() const {
     731        9453 :     return MiscUtils::GetUpTimeSeconds() < 0.20 * GetEndOfRibSendTime();
     732             : }
     733             : 
     734      217962 : bool BgpServer::enable_4byte_as() const {
     735      217962 :     return global_config()->enable_4byte_as();
     736             : }
     737             : 
     738         470 : void BgpServer::set_enable_4byte_as(bool flag) {
     739         470 :     global_config()->set_enable_4byte_as(flag);
     740         470 : }
     741             : 
     742       14389 : bool BgpServer::IsGRHelperModeEnabled() const {
     743             : 
     744             :     // Check if disabled in .conf file.
     745       14389 :     if (gr_helper_disable_)
     746        1892 :         return false;
     747             : 
     748             :     // Check if GR is disabled..
     749       12497 :     if (!global_config_->gr_enable())
     750        8578 :         return false;
     751             : 
     752             :     // Check from configuration.
     753        3919 :     return global_config_->gr_bgp_helper();
     754             : }
     755             : 
     756         176 : uint32_t BgpServer::num_routing_instance() const {
     757         176 :     assert(inst_mgr_.get());
     758         176 :     return inst_mgr_->count();
     759             : }
     760             : 
     761         176 : uint32_t BgpServer::num_deleted_routing_instance() const {
     762         176 :     assert(inst_mgr_.get());
     763         176 :     return inst_mgr_->deleted_count();
     764             : }
     765             : 
     766          64 : uint32_t BgpServer::get_output_queue_depth() const {
     767          64 :     uint32_t out_q_depth = 0;
     768          64 :     for (RoutingInstanceMgr::RoutingInstanceIterator rit = inst_mgr_->begin();
     769         256 :          rit != inst_mgr_->end(); ++rit) {
     770             :         RoutingInstance::RouteTableList const rt_list =
     771         192 :                      rit->second->GetTables();
     772         192 :         for (RoutingInstance::RouteTableList::const_iterator it =
     773        1600 :              rt_list.begin(); it != rt_list.end(); ++it) {
     774        1216 :             BgpTable *table = it->second;
     775             :             size_t markers;
     776        1216 :             out_q_depth += table->GetPendingRiboutsCount(&markers);
     777             :         }
     778         192 :     }
     779          64 :     return out_q_depth;
     780             : }
     781             : 
     782         880 : uint32_t BgpServer::num_service_chains() const {
     783         880 :     return inet_service_chain_mgr_->PendingQueueSize() +
     784         880 :         inet_service_chain_mgr_->ResolvedQueueSize() +
     785         880 :         inet6_service_chain_mgr_->PendingQueueSize() +
     786         880 :         inet6_service_chain_mgr_->ResolvedQueueSize() +
     787         880 :         evpn_service_chain_mgr_->PendingQueueSize() +
     788         880 :         evpn_service_chain_mgr_->ResolvedQueueSize() +
     789         880 :         evpn6_service_chain_mgr_->PendingQueueSize() +
     790         880 :         evpn6_service_chain_mgr_->ResolvedQueueSize();
     791             : }
     792             : 
     793         304 : uint32_t BgpServer::num_down_service_chains() const {
     794         304 :     return inet_service_chain_mgr_->PendingQueueSize() +
     795         304 :         inet_service_chain_mgr_->GetDownServiceChainCount() +
     796         304 :         inet6_service_chain_mgr_->PendingQueueSize() +
     797         304 :         inet6_service_chain_mgr_->GetDownServiceChainCount() +
     798         304 :         evpn_service_chain_mgr_->PendingQueueSize() +
     799         304 :         evpn_service_chain_mgr_->GetDownServiceChainCount() +
     800         304 :         evpn6_service_chain_mgr_->PendingQueueSize() +
     801         304 :         evpn6_service_chain_mgr_->GetDownServiceChainCount();
     802             : }
     803             : 
     804         186 : uint32_t BgpServer::num_static_routes() const {
     805         186 :     return GetStaticRouteCount();
     806             : }
     807             : 
     808         186 : uint32_t BgpServer::num_down_static_routes() const {
     809         186 :     return GetDownStaticRouteCount();
     810             : }
     811             : 
     812         176 : void BgpServer::VisitBgpPeers(BgpServer::VisitorFn fn) const {
     813         176 :     for (BgpPeerList::const_iterator loc = peer_list_.begin();
     814         326 :          loc != peer_list_.end(); ++loc) {
     815         150 :         fn(loc->second);
     816             :     }
     817         176 : }
     818             : 
     819        2084 : int BgpServer::RegisterAdminDownCallback(AdminDownCb callback) {
     820        2084 :     tbb::spin_rw_mutex::scoped_lock write_lock(rw_mutex_, true);
     821        2084 :     size_t i = admin_down_bmap_.find_first();
     822        2084 :     if (i == admin_down_bmap_.npos) {
     823        2084 :         i = admin_down_listeners_.size();
     824        2084 :         admin_down_listeners_.push_back(callback);
     825             :     } else {
     826           0 :         admin_down_bmap_.reset(i);
     827           0 :         if (admin_down_bmap_.none()) {
     828           0 :             admin_down_bmap_.clear();
     829             :         }
     830           0 :         admin_down_listeners_[i] = callback;
     831             :     }
     832        2084 :     return i;
     833        2084 : }
     834             : 
     835        2084 : void BgpServer::UnregisterAdminDownCallback(int listener) {
     836        2084 :     tbb::spin_rw_mutex::scoped_lock write_lock(rw_mutex_, true);
     837        2084 :     admin_down_listeners_[listener] = NULL;
     838        2084 :     if ((size_t) listener == admin_down_listeners_.size() - 1) {
     839        6252 :         while (!admin_down_listeners_.empty() &&
     840        2084 :             admin_down_listeners_.back() == NULL) {
     841        2084 :             admin_down_listeners_.pop_back();
     842             :         }
     843        2084 :         if (admin_down_bmap_.size() > admin_down_listeners_.size()) {
     844           0 :             admin_down_bmap_.resize(admin_down_listeners_.size());
     845             :         }
     846             :     } else {
     847           0 :         if ((size_t) listener >= admin_down_bmap_.size()) {
     848           0 :             admin_down_bmap_.resize(listener + 1);
     849             :         }
     850           0 :         admin_down_bmap_.set(listener);
     851             :     }
     852        2084 : }
     853             : 
     854          26 : void BgpServer::NotifyAdminDown() {
     855          26 :     tbb::spin_rw_mutex::scoped_lock read_lock(rw_mutex_, false);
     856          26 :     for (AdminDownListenersList::iterator iter = admin_down_listeners_.begin();
     857          42 :          iter != admin_down_listeners_.end(); ++iter) {
     858          16 :         if (*iter != NULL) {
     859          16 :             AdminDownCb cb = *iter;
     860          16 :             (cb)();
     861          16 :         }
     862             :     }
     863          26 : }
     864             : 
     865       16040 : int BgpServer::RegisterASNUpdateCallback(ASNUpdateCb callback) {
     866       16040 :     tbb::spin_rw_mutex::scoped_lock write_lock(rw_mutex_, true);
     867       16040 :     size_t i = asn_bmap_.find_first();
     868       16040 :     if (i == asn_bmap_.npos) {
     869       13993 :         i = asn_listeners_.size();
     870       13993 :         asn_listeners_.push_back(callback);
     871             :     } else {
     872        2047 :         asn_bmap_.reset(i);
     873        2047 :         if (asn_bmap_.none()) {
     874           3 :             asn_bmap_.clear();
     875             :         }
     876        2047 :         asn_listeners_[i] = callback;
     877             :     }
     878       16040 :     return i;
     879       16040 : }
     880             : 
     881       16038 : void BgpServer::UnregisterASNUpdateCallback(int listener) {
     882       16038 :     tbb::spin_rw_mutex::scoped_lock write_lock(rw_mutex_, true);
     883       16038 :     asn_listeners_[listener] = NULL;
     884       16038 :     if ((size_t) listener == asn_listeners_.size() - 1) {
     885       25903 :         while (!asn_listeners_.empty() && asn_listeners_.back() == NULL) {
     886       13989 :             asn_listeners_.pop_back();
     887             :         }
     888       11914 :         if (asn_bmap_.size() > asn_listeners_.size()) {
     889          80 :             asn_bmap_.resize(asn_listeners_.size());
     890             :         }
     891             :     } else {
     892        4124 :         if ((size_t) listener >= asn_bmap_.size()) {
     893        2080 :             asn_bmap_.resize(listener + 1);
     894             :         }
     895        4124 :         asn_bmap_.set(listener);
     896             :     }
     897       16038 : }
     898             : 
     899        7397 : void BgpServer::NotifyASNUpdate(as_t old_asn, as_t old_local_asn) {
     900        7397 :     tbb::spin_rw_mutex::scoped_lock read_lock(rw_mutex_, false);
     901        7397 :     for (ASNUpdateListenersList::iterator iter = asn_listeners_.begin();
     902       17259 :          iter != asn_listeners_.end(); ++iter) {
     903        9862 :         if (*iter != NULL) {
     904        9862 :             ASNUpdateCb cb = *iter;
     905        9862 :             (cb)(old_asn, old_local_asn);
     906        9862 :         }
     907             :     }
     908        7397 : }
     909             : 
     910       12442 : int BgpServer::RegisterDSCPUpdateCallback(DSCPUpdateCb callback) {
     911       12442 :     tbb::spin_rw_mutex::scoped_lock write_lock(rw_mutex_, true);
     912       12442 :     size_t i = dscp_bmap_.find_first();
     913       12442 :     if (i == dscp_bmap_.npos) {
     914       11425 :         i = dscp_listeners_.size();
     915       11425 :         dscp_listeners_.push_back(callback);
     916             :     } else {
     917        1017 :         dscp_bmap_.reset(i);
     918        1017 :         if (dscp_bmap_.none()) {
     919         255 :             dscp_bmap_.clear();
     920             :         }
     921        1017 :         dscp_listeners_[i] = callback;
     922             :     }
     923       12442 :     return i;
     924       12442 : }
     925             : 
     926       11651 : void BgpServer::UnregisterDSCPUpdateCallback(int listener) {
     927       11651 :     tbb::spin_rw_mutex::scoped_lock write_lock(rw_mutex_, true);
     928       11651 :     dscp_listeners_[listener] = NULL;
     929       11651 :     if ((size_t) listener == dscp_listeners_.size() - 1) {
     930       17571 :         while (!dscp_listeners_.empty() && dscp_listeners_.back() == NULL) {
     931       10634 :             dscp_listeners_.pop_back();
     932             :         }
     933        6937 :         if (dscp_bmap_.size() > dscp_listeners_.size()) {
     934        3072 :             dscp_bmap_.resize(dscp_listeners_.size());
     935             :         }
     936             :     } else {
     937        4714 :         if ((size_t) listener >= dscp_bmap_.size()) {
     938        2863 :             dscp_bmap_.resize(listener + 1);
     939             :         }
     940        4714 :         dscp_bmap_.set(listener);
     941             :     }
     942       11651 : }
     943             : 
     944           9 : void BgpServer::NotifyDSCPUpdate(int new_dscp_value) {
     945           9 :     tbb::spin_rw_mutex::scoped_lock read_lock(rw_mutex_, false);
     946           9 :     for (DSCPUpdateListenersList::iterator iter = dscp_listeners_.begin();
     947          22 :          iter != dscp_listeners_.end(); ++iter) {
     948          13 :         if (*iter != NULL) {
     949          13 :             DSCPUpdateCb cb = *iter;
     950          13 :             (cb)(new_dscp_value);
     951          13 :         }
     952             :     }
     953           9 : }
     954             : 
     955       53667 : int BgpServer::RegisterIdentifierUpdateCallback(IdentifierUpdateCb callback) {
     956       53667 :     tbb::spin_rw_mutex::scoped_lock write_lock(rw_mutex_, true);
     957       53667 :     size_t i = id_bmap_.find_first();
     958       53667 :     if (i == id_bmap_.npos) {
     959       53667 :         i = id_listeners_.size();
     960       53667 :         id_listeners_.push_back(callback);
     961             :     } else {
     962           0 :         id_bmap_.reset(i);
     963           0 :         if (id_bmap_.none()) {
     964           0 :             id_bmap_.clear();
     965             :         }
     966           0 :         id_listeners_[i] = callback;
     967             :     }
     968       53667 :     return i;
     969       53667 : }
     970             : 
     971       51583 : void BgpServer::UnregisterIdentifierUpdateCallback(int listener) {
     972       51583 :     tbb::spin_rw_mutex::scoped_lock write_lock(rw_mutex_, true);
     973       51583 :     id_listeners_[listener] = NULL;
     974       51583 :     if ((size_t) listener == id_listeners_.size() - 1) {
     975       64298 :         while (!id_listeners_.empty() && id_listeners_.back() == NULL) {
     976       49499 :             id_listeners_.pop_back();
     977             :         }
     978       14799 :         if (id_bmap_.size() > id_listeners_.size()) {
     979        7008 :             id_bmap_.resize(id_listeners_.size());
     980             :         }
     981             :     } else {
     982       36784 :         if ((size_t) listener >= id_bmap_.size()) {
     983       17447 :             id_bmap_.resize(listener + 1);
     984             :         }
     985       36784 :         id_bmap_.set(listener);
     986             :     }
     987       51583 : }
     988             : 
     989        7438 : void BgpServer::NotifyIdentifierUpdate(Ip4Address old_identifier) {
     990        7438 :     tbb::spin_rw_mutex::scoped_lock read_lock(rw_mutex_, false);
     991        7438 :     for (IdentifierUpdateListenersList::iterator iter = id_listeners_.begin();
     992       18454 :          iter != id_listeners_.end(); ++iter) {
     993       11016 :         if (*iter != NULL) {
     994       11016 :             IdentifierUpdateCb cb = *iter;
     995       11016 :             (cb)(old_identifier);
     996       11016 :         }
     997             :     }
     998        7438 : }
     999             : 
    1000         122 : void BgpServer::InsertStaticRouteMgr(IStaticRouteMgr *srt_manager) {
    1001         122 :     CHECK_CONCURRENCY("bgp::Config", "bgp::ConfigHelper");
    1002         122 :     tbb::spin_rw_mutex::scoped_lock write_lock(rw_mutex_, true);
    1003         122 :     srt_manager_list_.insert(srt_manager);
    1004         122 : }
    1005             : 
    1006         122 : void BgpServer::RemoveStaticRouteMgr(IStaticRouteMgr *srt_manager) {
    1007         122 :     CHECK_CONCURRENCY("bgp::Config", "bgp::ConfigHelper");
    1008         122 :     tbb::spin_rw_mutex::scoped_lock write_lock(rw_mutex_, true);
    1009         122 :     srt_manager_list_.erase(srt_manager);
    1010         122 : }
    1011             : 
    1012      275978 : void BgpServer::NotifyAllStaticRoutes() {
    1013      275978 :     CHECK_CONCURRENCY("bgp::Config", "bgp::ConfigHelper");
    1014      275978 :     tbb::spin_rw_mutex::scoped_lock write_lock(rw_mutex_, true);
    1015      275978 :     for (StaticRouteMgrList::iterator it = srt_manager_list_.begin();
    1016      279628 :          it != srt_manager_list_.end(); ++it) {
    1017        3650 :         IStaticRouteMgr *srt_manager = *it;
    1018        3650 :         srt_manager->NotifyAllRoutes();
    1019             :     }
    1020      275978 : }
    1021             : 
    1022         186 : uint32_t BgpServer::GetStaticRouteCount() const {
    1023         186 :     CHECK_CONCURRENCY("bgp::ShowCommand");
    1024         186 :     uint32_t count = 0;
    1025         186 :     for (StaticRouteMgrList::iterator it = srt_manager_list_.begin();
    1026         194 :          it != srt_manager_list_.end(); ++it) {
    1027           8 :         IStaticRouteMgr *srt_manager = *it;
    1028           8 :         count += srt_manager->GetRouteCount();
    1029             :     }
    1030         186 :     return count;
    1031             : }
    1032             : 
    1033         186 : uint32_t BgpServer::GetDownStaticRouteCount() const {
    1034         186 :     CHECK_CONCURRENCY("bgp::ShowCommand");
    1035         186 :     uint32_t count = 0;
    1036         186 :     for (StaticRouteMgrList::iterator it = srt_manager_list_.begin();
    1037         194 :          it != srt_manager_list_.end(); ++it) {
    1038           8 :         IStaticRouteMgr *srt_manager = *it;
    1039           8 :         count += srt_manager->GetDownRouteCount();
    1040             :     }
    1041         186 :     return count;
    1042             : }
    1043             : 
    1044         150 : void BgpServer::FillPeerStats(const BgpPeer *peer) const {
    1045         150 :     PeerStatsInfo stats;
    1046         150 :     PeerStats::FillPeerDebugStats(peer->peer_stats(), &stats);
    1047             : 
    1048         300 :     BgpPeerInfoData peer_info;
    1049         150 :     peer_info.set_name(peer->ToUVEKey());
    1050         150 :     peer_info.set_peer_stats_info(stats);
    1051         150 :     assert(!peer_info.get_name().empty());
    1052         150 :     BGP_UVE_SEND(BGPPeerInfo, peer_info);
    1053             : 
    1054         300 :     PeerStatsData peer_stats_data;
    1055         150 :     peer_stats_data.set_name(peer->ToUVEKey());
    1056         150 :     peer_stats_data.set_encoding("BGP");
    1057         150 :     PeerStats::FillPeerUpdateStats(peer->peer_stats(), &peer_stats_data);
    1058         150 :     assert(!peer_stats_data.get_name().empty());
    1059         150 :     BGP_UVE_SEND2(PeerStatsUve, peer_stats_data, "ObjectBgpPeer");
    1060             : 
    1061         150 :     PeerFlapInfo flap_info;
    1062         150 :     flap_info.set_flap_count(peer->flap_count());
    1063         150 :     flap_info.set_flap_time(peer->last_flap());
    1064             : 
    1065         300 :     PeerFlapData peer_flap_data;
    1066         150 :     peer_flap_data.set_name(peer->ToUVEKey());
    1067         150 :     peer_flap_data.set_encoding("BGP");
    1068         150 :     peer_flap_data.set_flap_info(flap_info);
    1069         150 :     assert(!peer_flap_data.get_name().empty());
    1070         150 :     BGP_UVE_SEND2(PeerFlap, peer_flap_data, "ObjectBgpPeer");
    1071         150 : }
    1072             : 
    1073         176 : bool BgpServer::CollectStats(BgpRouterState *state, bool first) const {
    1074         176 :     CHECK_CONCURRENCY("bgp::ShowCommand");
    1075             : 
    1076         176 :     VisitBgpPeers(boost::bind(&BgpServer::FillPeerStats, this, _1));
    1077         176 :     bool change = false;
    1078         176 :     uint32_t is_admin_down = admin_down();
    1079         176 :     if (first || is_admin_down != state->get_admin_down()) {
    1080           1 :         state->set_admin_down(is_admin_down);
    1081           1 :         change = true;
    1082             :     }
    1083             : 
    1084         176 :     string router_id = bgp_identifier_string();
    1085         176 :     if (first || router_id != state->get_router_id()) {
    1086           2 :         state->set_router_id(router_id);
    1087           2 :         change = true;
    1088             :     }
    1089             : 
    1090         176 :     uint32_t local_asn = local_autonomous_system();
    1091         176 :     if (first || local_asn != state->get_local_asn()) {
    1092           2 :         state->set_local_asn(local_asn);
    1093           2 :         change = true;
    1094             :     }
    1095             : 
    1096         176 :     uint32_t global_asn = autonomous_system();
    1097         176 :     if (first || global_asn != state->get_global_asn()) {
    1098           2 :         state->set_global_asn(global_asn);
    1099           2 :         change = true;
    1100             :     }
    1101             : 
    1102         176 :     uint32_t num_bgp = num_bgp_peer();
    1103         176 :     if (first || num_bgp != state->get_num_bgp_peer()) {
    1104           4 :         state->set_num_bgp_peer(num_bgp);
    1105           4 :         change = true;
    1106             :     }
    1107             : 
    1108         176 :     uint32_t num_up_bgp_peer = NumUpPeer();
    1109         176 :     if (first || num_up_bgp_peer != state->get_num_up_bgp_peer()) {
    1110          10 :         state->set_num_up_bgp_peer(num_up_bgp_peer);
    1111          10 :         change = true;
    1112             :     }
    1113             : 
    1114         176 :     uint32_t deleting_bgp_peer = num_deleting_bgp_peer();
    1115         176 :     if (first || deleting_bgp_peer != state->get_num_deleting_bgp_peer()) {
    1116           3 :         state->set_num_deleting_bgp_peer(deleting_bgp_peer);
    1117           3 :         change = true;
    1118             :     }
    1119             : 
    1120         176 :     uint32_t num_bgpaas = num_bgpaas_peer();
    1121         176 :     if (first || num_bgpaas != state->get_num_bgpaas_peer()) {
    1122           1 :         state->set_num_bgpaas_peer(num_bgpaas);
    1123           1 :         change = true;
    1124             :     }
    1125             : 
    1126         176 :     uint32_t num_up_bgpaas_peer = NumUpBgpaasPeer();
    1127         176 :     if (first || num_up_bgpaas_peer != state->get_num_up_bgpaas_peer()) {
    1128           1 :         state->set_num_up_bgpaas_peer(num_up_bgpaas_peer);
    1129           1 :         change = true;
    1130             :     }
    1131             : 
    1132         176 :     uint32_t deleting_bgpaas_peer = num_deleting_bgpaas_peer();
    1133         351 :     if (first || deleting_bgpaas_peer !=
    1134         175 :             state->get_num_deleting_bgpaas_peer()) {
    1135           1 :         state->set_num_deleting_bgpaas_peer(deleting_bgpaas_peer);
    1136           1 :         change = true;
    1137             :     }
    1138             : 
    1139         176 :     uint32_t num_ri = num_routing_instance();
    1140         176 :     if (first || num_ri != state->get_num_routing_instance()) {
    1141           7 :         state->set_num_routing_instance(num_ri);
    1142           7 :         change = true;
    1143             :     }
    1144             : 
    1145         176 :     uint32_t num_deleted_ri = num_deleted_routing_instance();
    1146         176 :     if (first || num_deleted_ri != state->get_num_deleted_routing_instance()) {
    1147           1 :         state->set_num_deleted_routing_instance(num_deleted_ri);
    1148           1 :         change = true;
    1149             :     }
    1150             : 
    1151         176 :     uint32_t service_chains = num_service_chains();
    1152         176 :     if (first || service_chains != state->get_num_service_chains()) {
    1153           1 :         state->set_num_service_chains(service_chains);
    1154           1 :         change = true;
    1155             :     }
    1156             : 
    1157         176 :     uint32_t down_service_chains = num_down_service_chains();
    1158         176 :     if (first || down_service_chains != state->get_num_down_service_chains()) {
    1159           1 :         state->set_num_down_service_chains(down_service_chains);
    1160           1 :         change = true;
    1161             :     }
    1162             : 
    1163         176 :     uint32_t static_routes = num_static_routes();
    1164         176 :     if (first || static_routes != state->get_num_static_routes()) {
    1165           1 :         state->set_num_static_routes(static_routes);
    1166           1 :         change = true;
    1167             :     }
    1168             : 
    1169         176 :     uint32_t down_static_routes = num_down_static_routes();
    1170         176 :     if (first || down_static_routes != state->get_num_down_static_routes()) {
    1171           1 :         state->set_num_down_static_routes(down_static_routes);
    1172           1 :         change = true;
    1173             :     }
    1174             : 
    1175         176 :     uint32_t out_load = inst_mgr_->SendTableStatsUve();
    1176         176 :     if (first || out_load != state->get_output_queue_depth()) {
    1177           3 :         state->set_output_queue_depth(out_load);
    1178           3 :         change = true;
    1179             :     }
    1180             : 
    1181         176 :     vector<string> bgp_config_peer_list;
    1182         474 :     BOOST_FOREACH(BgpConfigManager::NeighborMap::value_type value,
    1183             :         config_mgr_->NeighborMapItems(BgpConfigManager::kMasterInstance)) {
    1184         149 :         const BgpNeighborConfig *neighbor = value.second;
    1185         149 :         string name(BgpConfigManager::kMasterInstance);
    1186         149 :         name += ":";
    1187         149 :         name += localname();
    1188         149 :         name += ":";
    1189         149 :         name += neighbor->name();
    1190         149 :         bgp_config_peer_list.push_back(name);
    1191         298 :     }
    1192         176 :     sort(bgp_config_peer_list.begin(), bgp_config_peer_list.end());
    1193         176 :     if (first || bgp_config_peer_list != state->get_bgp_config_peer_list()) {
    1194           4 :         state->set_bgp_config_peer_list(bgp_config_peer_list);
    1195           4 :         change = true;
    1196             :     }
    1197             : 
    1198         176 :     vector<string> bgp_oper_peer_list;
    1199         176 :     const RoutingInstance *rtinstance = inst_mgr_->GetDefaultRoutingInstance();
    1200         176 :     const PeerManager *peer_manager = rtinstance->peer_manager();
    1201         176 :     for (const BgpPeer *peer = peer_manager->NextPeer(BgpPeerKey());
    1202         326 :         peer != NULL; peer = peer_manager->NextPeer(peer->peer_key())) {
    1203         150 :         bgp_oper_peer_list.push_back(peer->ToUVEKey());
    1204             :     }
    1205         176 :     sort(bgp_oper_peer_list.begin(), bgp_oper_peer_list.end());
    1206         176 :     if (first || bgp_oper_peer_list != state->get_bgp_oper_peer_list()) {
    1207           4 :         state->set_bgp_oper_peer_list(bgp_oper_peer_list);
    1208           4 :         change = true;
    1209             :     }
    1210             : 
    1211         176 :     return change;
    1212         176 : }
    1213             : 
    1214           0 : time_t BgpServer::GetRTargetTableLastUpdatedTimeStamp() const {
    1215           0 :     const RoutingInstanceMgr *ri_mgr = routing_instance_mgr();
    1216           0 :     const RTargetTable *rtarget_table = dynamic_cast<const RTargetTable *>(
    1217           0 :             ri_mgr->GetDefaultRoutingInstance()->GetTable(Address::RTARGET));
    1218           0 :     return rtarget_table->last_updated();
    1219             : }
    1220             : 
    1221        7438 : void BgpServer::UpdateBgpIdentifier(const Ip4Address &identifier) {
    1222        7438 :     Ip4Address old_identifier = bgp_identifier_;
    1223        7438 :     bgp_identifier_ = identifier;
    1224        7438 :     bgp_identifier_u32_ = identifier.to_ulong();
    1225        7438 :     NotifyIdentifierUpdate(old_identifier);
    1226        7438 : }

Generated by: LCOV version 1.14