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 9743 : explicit ConfigUpdater(BgpServer *server) : server_(server) {
52 9743 : BgpConfigManager::Observers obs;
53 : obs.instance = boost::bind(&ConfigUpdater::ProcessInstanceConfig,
54 9743 : this, _1, _2);
55 : obs.protocol = boost::bind(&ConfigUpdater::ProcessProtocolConfig,
56 9743 : this, _1, _2);
57 : obs.neighbor = boost::bind(&ConfigUpdater::ProcessNeighborConfig,
58 9743 : this, _1, _2);
59 : obs.policy = boost::bind(&ConfigUpdater::ProcessRoutingPolicyConfig,
60 9743 : this, _1, _2);
61 : obs.system= boost::bind(&ConfigUpdater::ProcessGlobalSystemConfig,
62 9743 : this, _1, _2);
63 : obs.qos = boost::bind(&ConfigUpdater::ProcessGlobalQosConfig,
64 9743 : this, _1, _2);
65 9743 : server->config_manager()->RegisterObservers(obs);
66 9743 : }
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 858 : void ProcessGlobalSystemConfig(const BgpGlobalSystemConfig *new_config,
78 : BgpConfigManager::EventType event) {
79 858 : bool clear_peers = false;
80 :
81 858 : 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 858 : 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 858 : 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 1716 : if (server_->global_config()->end_of_rib_timeout() !=
94 858 : 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 1716 : if (server_->global_config()->gr_bgp_helper() !=
100 858 : 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 1716 : if (server_->global_config()->enable_4byte_as() !=
106 858 : 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 1716 : if (server_->global_config()->fc_enabled() !=
113 858 : 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 1716 : if (server_->global_config()->nh_check_enabled() !=
120 858 : 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 1716 : if (server_->global_config()->always_compare_med() !=
128 858 : 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 1716 : if (server_->global_config()->rd_cluster_seed() !=
136 858 : 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 1716 : if (server_->global_config()->xmpp_hold_time() !=
143 858 : 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 1716 : if (server_->global_config()->all_tags_are_global() !=
150 858 : 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 858 : bool clear_bgpaas_peers = false;
156 :
157 : // Clear bgpaas peers if there's a change in bgpaas-port-start.
158 1716 : if (server_->global_config()->bgpaas_port_start() !=
159 858 : new_config->bgpaas_port_start()) {
160 1388 : server_->global_config()->set_bgpaas_port_start(
161 694 : new_config->bgpaas_port_start());
162 694 : clear_bgpaas_peers = true;
163 : }
164 :
165 : // Clear bgpaas peers if there's a change in bgpaas-port-end.
166 1716 : if (server_->global_config()->bgpaas_port_end() !=
167 858 : new_config->bgpaas_port_end()) {
168 1388 : server_->global_config()->set_bgpaas_port_end(
169 694 : new_config->bgpaas_port_end());
170 694 : clear_bgpaas_peers = true;
171 : }
172 :
173 858 : 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 858 : if (clear_peers || clear_bgpaas_peers)
182 838 : server_->ClearBgpaaSPeers();
183 858 : }
184 :
185 9051 : void ProcessProtocolConfig(const BgpProtocolConfig *protocol_config,
186 : BgpConfigManager::EventType event) {
187 9051 : const string &instance_name = protocol_config->instance_name();
188 :
189 : // We only support BGP sessions in master instance for now.
190 9051 : if (instance_name != BgpConfigManager::kMasterInstance) {
191 0 : return;
192 : }
193 :
194 9051 : if (event == BgpConfigManager::CFG_ADD ||
195 : event == BgpConfigManager::CFG_CHANGE) {
196 7672 : 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 9051 : void BgpServerConfigUpdate(string instance_name,
205 : const BgpProtocolConfig *config) {
206 9051 : boost::system::error_code ec;
207 9051 : uint32_t config_identifier = 0;
208 9051 : uint32_t config_autonomous_system = 0;
209 9051 : uint32_t config_local_autonomous_system = 0;
210 9051 : uint32_t config_hold_time = 0;
211 9051 : uint32_t config_cluster_id = 0;
212 9051 : bool config_admin_down = false;
213 9051 : if (config) {
214 7672 : config_admin_down = config->admin_down();
215 7672 : config_identifier = config->identifier();
216 7672 : config_autonomous_system = config->autonomous_system();
217 7672 : config_local_autonomous_system = config->local_autonomous_system();
218 7672 : config_cluster_id = config->cluster_id();
219 7672 : config_hold_time = config->hold_time();
220 : }
221 :
222 9051 : 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 9521 : if (config && !server_->session_manager()->Initialize(config->port()) &&
244 470 : !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 9051 : Ip4Address identifier(ntohl(config_identifier));
258 9051 : if (server_->bgp_identifier_ != identifier) {
259 7331 : 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 5900 : 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 7331 : server_->UpdateBgpIdentifier(identifier);
271 : }
272 :
273 9051 : bool notify_asn_update = false;
274 9051 : uint32_t old_asn = server_->autonomous_system_;
275 9051 : uint32_t old_local_asn = server_->local_autonomous_system_;
276 9051 : server_->autonomous_system_ = config_autonomous_system;
277 9051 : if (config_local_autonomous_system) {
278 1190 : server_->local_autonomous_system_ = config_local_autonomous_system;
279 : } else {
280 7861 : server_->local_autonomous_system_ = config_autonomous_system;
281 : }
282 :
283 9051 : if (server_->autonomous_system_ != old_asn) {
284 7355 : 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 5900 : 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 7355 : notify_asn_update = true;
295 : }
296 :
297 9051 : if (server_->local_autonomous_system_ != old_local_asn) {
298 7398 : 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 5900 : 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 7398 : notify_asn_update = true;
311 : }
312 :
313 9051 : if (notify_asn_update) {
314 7398 : server_->NotifyASNUpdate(old_asn, old_local_asn);
315 : }
316 :
317 9051 : 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 9051 : 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 9051 : ConnectionState::GetInstance()->Update();
337 9051 : }
338 :
339 16904 : void ProcessNeighborConfig(const BgpNeighborConfig *neighbor_config,
340 : BgpConfigManager::EventType event) {
341 16904 : string instance_name = neighbor_config->instance_name();
342 16904 : RoutingInstanceMgr *ri_mgr = server_->routing_instance_mgr();
343 16904 : RoutingInstance *rti = ri_mgr->GetRoutingInstance(instance_name);
344 16904 : if (!rti)
345 113 : return;
346 :
347 16791 : if (event == BgpConfigManager::CFG_ADD ||
348 : event == BgpConfigManager::CFG_CHANGE) {
349 10070 : if (rti->deleted())
350 6 : return;
351 10064 : PeerManager *peer_manager = rti->LocatePeerManager();
352 10064 : BgpPeer *peer = peer_manager->PeerLocate(server_, neighbor_config);
353 10064 : if (peer) {
354 10058 : server_->RemovePeer(peer->endpoint(), peer);
355 10058 : peer->ConfigUpdate(neighbor_config);
356 10058 : server_->InsertPeer(peer->endpoint(), peer);
357 : }
358 16785 : } else if (event == BgpConfigManager::CFG_DELETE) {
359 6721 : PeerManager *peer_manager = rti->peer_manager();
360 6721 : if (!peer_manager)
361 6 : return;
362 6715 : BgpPeer *peer = peer_manager->TriggerPeerDeletion(neighbor_config);
363 6715 : if (peer) {
364 6713 : server_->RemovePeer(peer->endpoint(), peer);
365 : }
366 : }
367 16904 : }
368 :
369 439 : void ProcessRoutingPolicyConfig(const BgpRoutingPolicyConfig *policy_config,
370 : BgpConfigManager::EventType event) {
371 439 : RoutingPolicyMgr *mgr = server_->routing_policy_mgr();
372 439 : if (event == BgpConfigManager::CFG_ADD) {
373 161 : mgr->CreateRoutingPolicy(policy_config);
374 278 : } else if (event == BgpConfigManager::CFG_CHANGE) {
375 235 : mgr->UpdateRoutingPolicy(policy_config);
376 43 : } else if (event == BgpConfigManager::CFG_DELETE) {
377 43 : mgr->DeleteRoutingPolicy(policy_config->name());
378 : }
379 439 : }
380 :
381 160972 : void ProcessInstanceConfig(const BgpInstanceConfig *instance_config,
382 : BgpConfigManager::EventType event) {
383 160972 : RoutingInstanceMgr *mgr = server_->routing_instance_mgr();
384 160972 : if (event == BgpConfigManager::CFG_ADD ||
385 : event == BgpConfigManager::CFG_CHANGE) {
386 150648 : mgr->LocateRoutingInstance(instance_config->name());
387 10324 : } else if (event == BgpConfigManager::CFG_DELETE) {
388 10324 : mgr->DeleteRoutingInstance(instance_config->name());
389 : }
390 160972 : }
391 :
392 : private:
393 : BgpServer *server_;
394 : };
395 :
396 : class BgpServer::DeleteActor : public LifetimeActor {
397 : public:
398 9743 : explicit DeleteActor(BgpServer *server)
399 9743 : : LifetimeActor(server->lifetime_manager()), server_(server) {
400 9743 : }
401 9639 : virtual bool MayDelete() const {
402 9639 : CHECK_CONCURRENCY("bgp::Config");
403 9639 : return server_->session_manager()->MayDelete();
404 : }
405 9639 : virtual void Shutdown() {
406 9639 : CHECK_CONCURRENCY("bgp::Config");
407 9639 : server_->session_manager()->Shutdown();
408 9639 : }
409 9639 : virtual void Destroy() {
410 9639 : CHECK_CONCURRENCY("bgp::Config");
411 9639 : server_->config_manager()->Terminate();
412 9639 : server_->session_manager()->Terminate();
413 9639 : TcpServerManager::DeleteServer(server_->session_manager());
414 9639 : server_->session_mgr_ = NULL;
415 9639 : server_->set_destroyed();
416 9639 : }
417 :
418 : private:
419 : BgpServer *server_;
420 : };
421 :
422 27588 : bool BgpServer::IsDeleted() const {
423 27588 : 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 2179696 : bool BgpServer::IsReadyForDeletion() {
433 2179696 : CHECK_CONCURRENCY("bgp::Config");
434 :
435 2179696 : static TaskScheduler *scheduler = TaskScheduler::GetInstance();
436 2179696 : static int db_table_task_id = scheduler->GetTaskId("db::DBTable");
437 : static int resolver_path_task_id =
438 2179696 : scheduler->GetTaskId("bgp::ResolverPath");
439 : static int resolver_nexthop_task_id =
440 2179696 : 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 3895523 : if (!scheduler->IsTaskGroupEmpty(resolver_path_task_id) ||
446 1715827 : !scheduler->IsTaskGroupEmpty(resolver_nexthop_task_id)) {
447 463869 : return false;
448 : }
449 :
450 : // Check if the membership manager queue is empty.
451 1715827 : if (!membership_mgr_->IsQueueEmpty()) {
452 49020 : return false;
453 : }
454 :
455 : // Check if the Service Chain Manager Work Queues are empty.
456 1666807 : if (!inet_service_chain_mgr_->IsQueueEmpty() ||
457 1666474 : !inet6_service_chain_mgr_->IsQueueEmpty() ||
458 4999463 : !evpn_service_chain_mgr_->IsQueueEmpty() ||
459 1666182 : !evpn6_service_chain_mgr_->IsQueueEmpty()) {
460 625 : return false;
461 : }
462 :
463 : // Check if the DB requests queue and change list is empty.
464 1666182 : if (!db_.IsDBQueueEmpty()) {
465 120863 : 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 1545319 : if (!rtarget_group_mgr_->IsRTargetRoutesProcessed()) {
472 1195 : 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 1544124 : if (!scheduler->IsTaskGroupEmpty(db_table_task_id)) {
479 45354 : return false;
480 : }
481 :
482 1498770 : return true;
483 : }
484 :
485 9743 : BgpServer::BgpServer(EventManager *evm)
486 9743 : : admin_down_(false),
487 9743 : cluster_id_(0),
488 9743 : autonomous_system_(0),
489 9743 : local_autonomous_system_(0),
490 9743 : bgp_identifier_(0),
491 9743 : bgp_identifier_u32_(0),
492 9743 : hold_time_(0),
493 9743 : gr_helper_disable_(false),
494 9743 : lifetime_manager_(BgpStaticObjectFactory::Create<BgpLifetimeManager>(this,
495 : TaskScheduler::GetInstance()->GetTaskId("bgp::Config"))),
496 9743 : deleter_(new DeleteActor(this)),
497 9743 : destroyed_(false),
498 9743 : logging_disabled_(false),
499 9743 : mvpn_ipv4_enable_(false),
500 9743 : ignore_aspath_(false),
501 9743 : aspath_db_(new AsPathDB(this)),
502 9743 : aspath_4byte_db_(new AsPath4ByteDB(this)),
503 9743 : as4path_db_(new As4PathDB(this)),
504 9743 : olist_db_(new BgpOListDB(this)),
505 9743 : cluster_list_db_(new ClusterListDB(this)),
506 9743 : comm_db_(new CommunityDB(this)),
507 9743 : edge_discovery_db_(new EdgeDiscoveryDB(this)),
508 9743 : edge_forwarding_db_(new EdgeForwardingDB(this)),
509 9743 : extcomm_db_(new ExtCommunityDB(this)),
510 9743 : largecomm_db_(new LargeCommunityDB(this)),
511 9743 : ovnpath_db_(new OriginVnPathDB(this)),
512 9743 : pmsi_tunnel_db_(new PmsiTunnelDB(this)),
513 9743 : attr_db_(new BgpAttrDB(this)),
514 9743 : session_mgr_(BgpStaticObjectFactory::Create<BgpSessionManager>(evm, this)),
515 9743 : update_sender_(new BgpUpdateSender(this)),
516 9743 : inst_mgr_(BgpStaticObjectFactory::Create<RoutingInstanceMgr>(this)),
517 9743 : policy_mgr_(BgpStaticObjectFactory::Create<RoutingPolicyMgr>(this)),
518 9743 : rtarget_group_mgr_(BgpStaticObjectFactory::Create<RTargetGroupMgr>(this)),
519 9743 : membership_mgr_(BgpStaticObjectFactory::Create<BgpMembershipManager>(this)),
520 9743 : inet_condition_listener_(new BgpConditionListener(this)),
521 9743 : inet6_condition_listener_(new BgpConditionListener(this)),
522 9743 : evpn_condition_listener_(new BgpConditionListener(this)),
523 9743 : evpn6_condition_listener_(new BgpConditionListener(this)),
524 9743 : inetvpn_replicator_(new RoutePathReplicator(this, Address::INETVPN)),
525 9743 : ermvpn_replicator_(new RoutePathReplicator(this, Address::ERMVPN)),
526 9743 : mvpn_replicator_(new RoutePathReplicator(this, Address::MVPN)),
527 9743 : evpn_replicator_(new RoutePathReplicator(this, Address::EVPN)),
528 9743 : inet6vpn_replicator_(new RoutePathReplicator(this, Address::INET6VPN)),
529 9743 : inet_service_chain_mgr_(
530 9743 : BgpStaticObjectFactory::Create<IServiceChainMgr, SCAddress::INET>(this)),
531 9743 : inet6_service_chain_mgr_(
532 9743 : BgpStaticObjectFactory::Create<IServiceChainMgr, SCAddress::INET6>(this)),
533 9743 : evpn_service_chain_mgr_(
534 9743 : BgpStaticObjectFactory::Create<IServiceChainMgr, SCAddress::EVPN>(this)),
535 9743 : evpn6_service_chain_mgr_(
536 9743 : BgpStaticObjectFactory::Create<IServiceChainMgr, SCAddress::EVPN6>(this)),
537 9743 : global_config_(new BgpGlobalSystemConfig()),
538 9743 : global_qos_(new BgpGlobalQosConfig()),
539 9743 : config_mgr_(BgpStaticObjectFactory::Create<BgpConfigManager>(this)),
540 29229 : updater_(new ConfigUpdater(this)) {
541 9743 : bgp_count_ = 0;
542 9743 : num_up_peer_ = 0;
543 9743 : deleting_count_ = 0;
544 9743 : bgpaas_count_ = 0;
545 9743 : num_up_bgpaas_peer_ = 0;
546 9743 : deleting_bgpaas_count_ = 0;
547 9743 : message_build_error_ = 0;
548 9743 : }
549 :
550 11293 : BgpServer::~BgpServer() {
551 9743 : assert(deleting_count_ == 0);
552 9743 : assert(deleting_bgpaas_count_ == 0);
553 9743 : assert(srt_manager_list_.empty());
554 11293 : }
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 6073187 : string BgpServer::ToString() const {
565 6073187 : return bgp_identifier_.to_string();
566 : }
567 :
568 9701 : void BgpServer::Shutdown() {
569 9701 : deleter_->Delete();
570 9701 : }
571 :
572 58458 : LifetimeActor *BgpServer::deleter() {
573 58458 : return deleter_.get();
574 : }
575 :
576 6509 : bool BgpServer::HasSelfConfiguration() const {
577 6509 : if (!bgp_identifier_u32())
578 321 : return false;
579 6188 : if (!local_autonomous_system())
580 0 : return false;
581 6188 : if (!autonomous_system())
582 0 : return false;
583 6188 : return true;
584 : }
585 :
586 10360 : int BgpServer::RegisterPeer(BgpPeer *peer) {
587 10360 : CHECK_CONCURRENCY("bgp::Config");
588 :
589 10360 : if (peer->IsRouterTypeBGPaaS()) {
590 114 : bgpaas_count_++;
591 : } else {
592 10246 : bgp_count_++;
593 : }
594 :
595 10360 : BgpPeerList::iterator loc;
596 : bool result;
597 10360 : tie(loc, result) = peer_list_.insert(make_pair(peer->peer_name(), peer));
598 10360 : assert(result);
599 10360 : assert(loc->second == peer);
600 :
601 10360 : size_t bit = peer_bmap_.find_first();
602 10360 : if (bit == peer_bmap_.npos) {
603 9343 : bit = peer_bmap_.size();
604 9343 : peer_bmap_.resize(bit + 1, true);
605 : }
606 10360 : peer_bmap_.reset(bit);
607 10360 : return bit;
608 : }
609 :
610 9576 : void BgpServer::UnregisterPeer(BgpPeer *peer) {
611 9576 : CHECK_CONCURRENCY("bgp::Config");
612 :
613 9576 : if (peer->IsRouterTypeBGPaaS()) {
614 112 : assert(bgpaas_count_);
615 112 : bgpaas_count_--;
616 : } else {
617 9464 : assert(bgp_count_);
618 9464 : bgp_count_--;
619 : }
620 :
621 9576 : BgpPeerList::iterator loc = peer_list_.find(peer->peer_name());
622 9576 : assert(loc != peer_list_.end());
623 9576 : peer_list_.erase(loc);
624 :
625 9576 : peer_bmap_.set(peer->GetIndex());
626 18135 : for (size_t i = peer_bmap_.size(); i != 0; i--) {
627 15039 : if (peer_bmap_[i-1] != true) {
628 6480 : if (i != peer_bmap_.size()) {
629 2002 : peer_bmap_.resize(i);
630 : }
631 6480 : return;
632 : }
633 : }
634 3096 : 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 2844 : BgpPeer *BgpServer::FindNextPeer(const string &name) {
643 2844 : BgpPeerList::iterator loc = peer_list_.upper_bound(name);
644 2844 : return (loc != peer_list_.end() ? loc->second : NULL);
645 : }
646 :
647 10169 : void BgpServer::InsertPeer(TcpSession::Endpoint remote, BgpPeer *peer) {
648 10169 : if (!remote.port() && remote.address().is_unspecified())
649 9975 : return;
650 194 : endpoint_peer_list_.insert(make_pair(remote, peer));
651 : }
652 :
653 16771 : void BgpServer::RemovePeer(TcpSession::Endpoint remote, BgpPeer *peer) {
654 16771 : EndpointPeerList::iterator loc = endpoint_peer_list_.lower_bound(remote);
655 16772 : 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 16771 : }
663 :
664 838 : void BgpServer::ClearBgpaaSPeers() {
665 838 : for (auto &i : endpoint_peer_list_) {
666 0 : i.second->Clear(BgpProto::Notification::OtherConfigChange);
667 : }
668 838 : }
669 :
670 842 : BgpPeer *BgpServer::FindPeer(TcpSession::Endpoint remote) const {
671 842 : EndpointPeerList::const_iterator loc = endpoint_peer_list_.find(remote);
672 842 : 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 662208 : const string &BgpServer::localname() const {
687 662208 : return config_mgr_->localname();
688 : }
689 :
690 298425 : boost::asio::io_context *BgpServer::ioservice() {
691 298425 : 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 644082 : bool BgpServer::IsNextHopCheckEnabled() const {
699 644082 : if (!global_config_->fc_enabled())
700 643961 : return false;
701 140 : return (global_config_->nh_check_enabled());
702 : }
703 :
704 4122 : uint16_t BgpServer::GetGracefulRestartTime() const {
705 4122 : if (!global_config_->gr_enable())
706 1 : return 0;
707 4121 : return global_config_->gr_time();
708 : }
709 :
710 8223 : uint32_t BgpServer::GetLongLivedGracefulRestartTime() const {
711 8223 : if (!global_config_->gr_enable())
712 1 : return 0;
713 8222 : 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 17154 : uint32_t BgpServer::GetEndOfRibReceiveTime() const {
723 17154 : return global_config_->end_of_rib_timeout();
724 : }
725 :
726 9988 : uint32_t BgpServer::GetEndOfRibSendTime() const {
727 9988 : return global_config_->end_of_rib_timeout();
728 : }
729 :
730 9588 : bool BgpServer::IsServerStartingUp() const {
731 9588 : return MiscUtils::GetUpTimeSeconds() < 0.20 * GetEndOfRibSendTime();
732 : }
733 :
734 219603 : bool BgpServer::enable_4byte_as() const {
735 219603 : return global_config()->enable_4byte_as();
736 : }
737 :
738 471 : void BgpServer::set_enable_4byte_as(bool flag) {
739 471 : global_config()->set_enable_4byte_as(flag);
740 471 : }
741 :
742 14728 : bool BgpServer::IsGRHelperModeEnabled() const {
743 :
744 : // Check if disabled in .conf file.
745 14728 : if (gr_helper_disable_)
746 1893 : return false;
747 :
748 : // Check if GR is disabled..
749 12835 : if (!global_config_->gr_enable())
750 8581 : return false;
751 :
752 : // Check from configuration.
753 4256 : return global_config_->gr_bgp_helper();
754 : }
755 :
756 219 : uint32_t BgpServer::num_routing_instance() const {
757 219 : assert(inst_mgr_.get());
758 219 : return inst_mgr_->count();
759 : }
760 :
761 219 : uint32_t BgpServer::num_deleted_routing_instance() const {
762 219 : assert(inst_mgr_.get());
763 219 : return inst_mgr_->deleted_count();
764 : }
765 :
766 52 : uint32_t BgpServer::get_output_queue_depth() const {
767 52 : uint32_t out_q_depth = 0;
768 52 : for (RoutingInstanceMgr::RoutingInstanceIterator rit = inst_mgr_->begin();
769 208 : rit != inst_mgr_->end(); ++rit) {
770 : RoutingInstance::RouteTableList const rt_list =
771 156 : rit->second->GetTables();
772 156 : for (RoutingInstance::RouteTableList::const_iterator it =
773 1300 : rt_list.begin(); it != rt_list.end(); ++it) {
774 988 : BgpTable *table = it->second;
775 : size_t markers;
776 988 : out_q_depth += table->GetPendingRiboutsCount(&markers);
777 : }
778 156 : }
779 52 : return out_q_depth;
780 : }
781 :
782 923 : uint32_t BgpServer::num_service_chains() const {
783 923 : return inet_service_chain_mgr_->PendingQueueSize() +
784 923 : inet_service_chain_mgr_->ResolvedQueueSize() +
785 923 : inet6_service_chain_mgr_->PendingQueueSize() +
786 923 : inet6_service_chain_mgr_->ResolvedQueueSize() +
787 923 : evpn_service_chain_mgr_->PendingQueueSize() +
788 923 : evpn_service_chain_mgr_->ResolvedQueueSize() +
789 923 : evpn6_service_chain_mgr_->PendingQueueSize() +
790 923 : evpn6_service_chain_mgr_->ResolvedQueueSize();
791 : }
792 :
793 347 : uint32_t BgpServer::num_down_service_chains() const {
794 347 : return inet_service_chain_mgr_->PendingQueueSize() +
795 347 : inet_service_chain_mgr_->GetDownServiceChainCount() +
796 347 : inet6_service_chain_mgr_->PendingQueueSize() +
797 347 : inet6_service_chain_mgr_->GetDownServiceChainCount() +
798 347 : evpn_service_chain_mgr_->PendingQueueSize() +
799 347 : evpn_service_chain_mgr_->GetDownServiceChainCount() +
800 347 : evpn6_service_chain_mgr_->PendingQueueSize() +
801 347 : evpn6_service_chain_mgr_->GetDownServiceChainCount();
802 : }
803 :
804 229 : uint32_t BgpServer::num_static_routes() const {
805 229 : return GetStaticRouteCount();
806 : }
807 :
808 229 : uint32_t BgpServer::num_down_static_routes() const {
809 229 : return GetDownStaticRouteCount();
810 : }
811 :
812 219 : void BgpServer::VisitBgpPeers(BgpServer::VisitorFn fn) const {
813 219 : for (BgpPeerList::const_iterator loc = peer_list_.begin();
814 415 : loc != peer_list_.end(); ++loc) {
815 196 : fn(loc->second);
816 : }
817 219 : }
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 16041 : int BgpServer::RegisterASNUpdateCallback(ASNUpdateCb callback) {
866 16041 : tbb::spin_rw_mutex::scoped_lock write_lock(rw_mutex_, true);
867 16041 : size_t i = asn_bmap_.find_first();
868 16041 : if (i == asn_bmap_.npos) {
869 13994 : i = asn_listeners_.size();
870 13994 : 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 16041 : return i;
879 16041 : }
880 :
881 16039 : void BgpServer::UnregisterASNUpdateCallback(int listener) {
882 16039 : tbb::spin_rw_mutex::scoped_lock write_lock(rw_mutex_, true);
883 16039 : asn_listeners_[listener] = NULL;
884 16039 : if ((size_t) listener == asn_listeners_.size() - 1) {
885 25904 : while (!asn_listeners_.empty() && asn_listeners_.back() == NULL) {
886 13990 : asn_listeners_.pop_back();
887 : }
888 11914 : if (asn_bmap_.size() > asn_listeners_.size()) {
889 82 : asn_bmap_.resize(asn_listeners_.size());
890 : }
891 : } else {
892 4125 : if ((size_t) listener >= asn_bmap_.size()) {
893 2081 : asn_bmap_.resize(listener + 1);
894 : }
895 4125 : asn_bmap_.set(listener);
896 : }
897 16039 : }
898 :
899 7398 : void BgpServer::NotifyASNUpdate(as_t old_asn, as_t old_local_asn) {
900 7398 : tbb::spin_rw_mutex::scoped_lock read_lock(rw_mutex_, false);
901 7398 : for (ASNUpdateListenersList::iterator iter = asn_listeners_.begin();
902 17261 : iter != asn_listeners_.end(); ++iter) {
903 9863 : if (*iter != NULL) {
904 9863 : ASNUpdateCb cb = *iter;
905 9863 : (cb)(old_asn, old_local_asn);
906 9863 : }
907 : }
908 7398 : }
909 :
910 12444 : int BgpServer::RegisterDSCPUpdateCallback(DSCPUpdateCb callback) {
911 12444 : tbb::spin_rw_mutex::scoped_lock write_lock(rw_mutex_, true);
912 12444 : size_t i = dscp_bmap_.find_first();
913 12444 : if (i == dscp_bmap_.npos) {
914 11427 : i = dscp_listeners_.size();
915 11427 : 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 12444 : return i;
924 12444 : }
925 :
926 11653 : void BgpServer::UnregisterDSCPUpdateCallback(int listener) {
927 11653 : tbb::spin_rw_mutex::scoped_lock write_lock(rw_mutex_, true);
928 11653 : dscp_listeners_[listener] = NULL;
929 11653 : if ((size_t) listener == dscp_listeners_.size() - 1) {
930 17547 : while (!dscp_listeners_.empty() && dscp_listeners_.back() == NULL) {
931 10636 : dscp_listeners_.pop_back();
932 : }
933 6911 : if (dscp_bmap_.size() > dscp_listeners_.size()) {
934 2976 : dscp_bmap_.resize(dscp_listeners_.size());
935 : }
936 : } else {
937 4742 : if ((size_t) listener >= dscp_bmap_.size()) {
938 2880 : dscp_bmap_.resize(listener + 1);
939 : }
940 4742 : dscp_bmap_.set(listener);
941 : }
942 11653 : }
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 53668 : int BgpServer::RegisterIdentifierUpdateCallback(IdentifierUpdateCb callback) {
956 53668 : tbb::spin_rw_mutex::scoped_lock write_lock(rw_mutex_, true);
957 53668 : size_t i = id_bmap_.find_first();
958 53668 : if (i == id_bmap_.npos) {
959 53668 : i = id_listeners_.size();
960 53668 : 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 53668 : return i;
969 53668 : }
970 :
971 51584 : void BgpServer::UnregisterIdentifierUpdateCallback(int listener) {
972 51584 : tbb::spin_rw_mutex::scoped_lock write_lock(rw_mutex_, true);
973 51584 : id_listeners_[listener] = NULL;
974 51584 : if ((size_t) listener == id_listeners_.size() - 1) {
975 64212 : while (!id_listeners_.empty() && id_listeners_.back() == NULL) {
976 49500 : id_listeners_.pop_back();
977 : }
978 14712 : if (id_bmap_.size() > id_listeners_.size()) {
979 6958 : id_bmap_.resize(id_listeners_.size());
980 : }
981 : } else {
982 36872 : if ((size_t) listener >= id_bmap_.size()) {
983 17437 : id_bmap_.resize(listener + 1);
984 : }
985 36872 : id_bmap_.set(listener);
986 : }
987 51584 : }
988 :
989 7439 : void BgpServer::NotifyIdentifierUpdate(Ip4Address old_identifier) {
990 7439 : tbb::spin_rw_mutex::scoped_lock read_lock(rw_mutex_, false);
991 7439 : for (IdentifierUpdateListenersList::iterator iter = id_listeners_.begin();
992 18456 : iter != id_listeners_.end(); ++iter) {
993 11017 : if (*iter != NULL) {
994 11017 : IdentifierUpdateCb cb = *iter;
995 11017 : (cb)(old_identifier);
996 11017 : }
997 : }
998 7439 : }
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 275982 : void BgpServer::NotifyAllStaticRoutes() {
1013 275982 : CHECK_CONCURRENCY("bgp::Config", "bgp::ConfigHelper");
1014 275981 : tbb::spin_rw_mutex::scoped_lock write_lock(rw_mutex_, true);
1015 275981 : for (StaticRouteMgrList::iterator it = srt_manager_list_.begin();
1016 279647 : it != srt_manager_list_.end(); ++it) {
1017 3666 : IStaticRouteMgr *srt_manager = *it;
1018 3666 : srt_manager->NotifyAllRoutes();
1019 : }
1020 275981 : }
1021 :
1022 229 : uint32_t BgpServer::GetStaticRouteCount() const {
1023 229 : CHECK_CONCURRENCY("bgp::ShowCommand");
1024 229 : uint32_t count = 0;
1025 229 : for (StaticRouteMgrList::iterator it = srt_manager_list_.begin();
1026 237 : it != srt_manager_list_.end(); ++it) {
1027 8 : IStaticRouteMgr *srt_manager = *it;
1028 8 : count += srt_manager->GetRouteCount();
1029 : }
1030 229 : return count;
1031 : }
1032 :
1033 229 : uint32_t BgpServer::GetDownStaticRouteCount() const {
1034 229 : CHECK_CONCURRENCY("bgp::ShowCommand");
1035 229 : uint32_t count = 0;
1036 229 : for (StaticRouteMgrList::iterator it = srt_manager_list_.begin();
1037 237 : it != srt_manager_list_.end(); ++it) {
1038 8 : IStaticRouteMgr *srt_manager = *it;
1039 8 : count += srt_manager->GetDownRouteCount();
1040 : }
1041 229 : return count;
1042 : }
1043 :
1044 196 : void BgpServer::FillPeerStats(const BgpPeer *peer) const {
1045 196 : PeerStatsInfo stats;
1046 196 : PeerStats::FillPeerDebugStats(peer->peer_stats(), &stats);
1047 :
1048 392 : BgpPeerInfoData peer_info;
1049 196 : peer_info.set_name(peer->ToUVEKey());
1050 196 : peer_info.set_peer_stats_info(stats);
1051 196 : assert(!peer_info.get_name().empty());
1052 196 : BGP_UVE_SEND(BGPPeerInfo, peer_info);
1053 :
1054 392 : PeerStatsData peer_stats_data;
1055 196 : peer_stats_data.set_name(peer->ToUVEKey());
1056 196 : peer_stats_data.set_encoding("BGP");
1057 196 : PeerStats::FillPeerUpdateStats(peer->peer_stats(), &peer_stats_data);
1058 196 : assert(!peer_stats_data.get_name().empty());
1059 196 : BGP_UVE_SEND2(PeerStatsUve, peer_stats_data, "ObjectBgpPeer");
1060 :
1061 196 : PeerFlapInfo flap_info;
1062 196 : flap_info.set_flap_count(peer->flap_count());
1063 196 : flap_info.set_flap_time(peer->last_flap());
1064 :
1065 392 : PeerFlapData peer_flap_data;
1066 196 : peer_flap_data.set_name(peer->ToUVEKey());
1067 196 : peer_flap_data.set_encoding("BGP");
1068 196 : peer_flap_data.set_flap_info(flap_info);
1069 196 : assert(!peer_flap_data.get_name().empty());
1070 196 : BGP_UVE_SEND2(PeerFlap, peer_flap_data, "ObjectBgpPeer");
1071 196 : }
1072 :
1073 219 : bool BgpServer::CollectStats(BgpRouterState *state, bool first) const {
1074 219 : CHECK_CONCURRENCY("bgp::ShowCommand");
1075 :
1076 219 : VisitBgpPeers(boost::bind(&BgpServer::FillPeerStats, this, _1));
1077 219 : bool change = false;
1078 219 : uint32_t is_admin_down = admin_down();
1079 219 : 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 219 : string router_id = bgp_identifier_string();
1085 219 : if (first || router_id != state->get_router_id()) {
1086 2 : state->set_router_id(router_id);
1087 2 : change = true;
1088 : }
1089 :
1090 219 : uint32_t local_asn = local_autonomous_system();
1091 219 : if (first || local_asn != state->get_local_asn()) {
1092 2 : state->set_local_asn(local_asn);
1093 2 : change = true;
1094 : }
1095 :
1096 219 : uint32_t global_asn = autonomous_system();
1097 219 : if (first || global_asn != state->get_global_asn()) {
1098 2 : state->set_global_asn(global_asn);
1099 2 : change = true;
1100 : }
1101 :
1102 219 : uint32_t num_bgp = num_bgp_peer();
1103 219 : 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 219 : uint32_t num_up_bgp_peer = NumUpPeer();
1109 219 : 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 219 : uint32_t deleting_bgp_peer = num_deleting_bgp_peer();
1115 219 : 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 219 : uint32_t num_bgpaas = num_bgpaas_peer();
1121 219 : 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 219 : uint32_t num_up_bgpaas_peer = NumUpBgpaasPeer();
1127 219 : 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 219 : uint32_t deleting_bgpaas_peer = num_deleting_bgpaas_peer();
1133 437 : if (first || deleting_bgpaas_peer !=
1134 218 : state->get_num_deleting_bgpaas_peer()) {
1135 1 : state->set_num_deleting_bgpaas_peer(deleting_bgpaas_peer);
1136 1 : change = true;
1137 : }
1138 :
1139 219 : uint32_t num_ri = num_routing_instance();
1140 219 : if (first || num_ri != state->get_num_routing_instance()) {
1141 12 : state->set_num_routing_instance(num_ri);
1142 12 : change = true;
1143 : }
1144 :
1145 219 : uint32_t num_deleted_ri = num_deleted_routing_instance();
1146 219 : 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 219 : uint32_t service_chains = num_service_chains();
1152 219 : 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 219 : uint32_t down_service_chains = num_down_service_chains();
1158 219 : 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 219 : uint32_t static_routes = num_static_routes();
1164 219 : 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 219 : uint32_t down_static_routes = num_down_static_routes();
1170 219 : 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 219 : uint32_t out_load = inst_mgr_->SendTableStatsUve();
1176 219 : if (first || out_load != state->get_output_queue_depth()) {
1177 4 : state->set_output_queue_depth(out_load);
1178 4 : change = true;
1179 : }
1180 :
1181 219 : vector<string> bgp_config_peer_list;
1182 609 : BOOST_FOREACH(BgpConfigManager::NeighborMap::value_type value,
1183 : config_mgr_->NeighborMapItems(BgpConfigManager::kMasterInstance)) {
1184 195 : const BgpNeighborConfig *neighbor = value.second;
1185 195 : string name(BgpConfigManager::kMasterInstance);
1186 195 : name += ":";
1187 195 : name += localname();
1188 195 : name += ":";
1189 195 : name += neighbor->name();
1190 195 : bgp_config_peer_list.push_back(name);
1191 390 : }
1192 219 : sort(bgp_config_peer_list.begin(), bgp_config_peer_list.end());
1193 219 : if (first || bgp_config_peer_list != state->get_bgp_config_peer_list()) {
1194 6 : state->set_bgp_config_peer_list(bgp_config_peer_list);
1195 6 : change = true;
1196 : }
1197 :
1198 219 : vector<string> bgp_oper_peer_list;
1199 219 : const RoutingInstance *rtinstance = inst_mgr_->GetDefaultRoutingInstance();
1200 219 : const PeerManager *peer_manager = rtinstance->peer_manager();
1201 219 : for (const BgpPeer *peer = peer_manager->NextPeer(BgpPeerKey());
1202 415 : peer != NULL; peer = peer_manager->NextPeer(peer->peer_key())) {
1203 196 : bgp_oper_peer_list.push_back(peer->ToUVEKey());
1204 : }
1205 219 : sort(bgp_oper_peer_list.begin(), bgp_oper_peer_list.end());
1206 219 : 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 219 : return change;
1212 219 : }
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 7439 : void BgpServer::UpdateBgpIdentifier(const Ip4Address &identifier) {
1222 7439 : Ip4Address old_identifier = bgp_identifier_;
1223 7439 : bgp_identifier_ = identifier;
1224 7439 : bgp_identifier_u32_ = identifier.to_ulong();
1225 7439 : NotifyIdentifierUpdate(old_identifier);
1226 7439 : }
|