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