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 32 : explicit ConfigUpdater(BgpServer *server) : server_(server) {
52 32 : BgpConfigManager::Observers obs;
53 : obs.instance = boost::bind(&ConfigUpdater::ProcessInstanceConfig,
54 32 : this, _1, _2);
55 : obs.protocol = boost::bind(&ConfigUpdater::ProcessProtocolConfig,
56 32 : this, _1, _2);
57 : obs.neighbor = boost::bind(&ConfigUpdater::ProcessNeighborConfig,
58 32 : this, _1, _2);
59 : obs.policy = boost::bind(&ConfigUpdater::ProcessRoutingPolicyConfig,
60 32 : this, _1, _2);
61 : obs.system= boost::bind(&ConfigUpdater::ProcessGlobalSystemConfig,
62 32 : this, _1, _2);
63 : obs.qos = boost::bind(&ConfigUpdater::ProcessGlobalQosConfig,
64 32 : this, _1, _2);
65 32 : server->config_manager()->RegisterObservers(obs);
66 32 : }
67 :
68 0 : void ProcessGlobalQosConfig(const BgpGlobalQosConfig *qos,
69 : BgpConfigManager::EventType event) {
70 0 : if (qos->control_dscp() != server_->global_qos()->control_dscp()) {
71 0 : server_->global_qos()->set_control_dscp(qos->control_dscp());
72 0 : server_->NotifyDSCPUpdate(qos->control_dscp());
73 : }
74 0 : server_->global_qos()->set_analytics_dscp(qos->analytics_dscp());
75 0 : }
76 :
77 0 : void ProcessGlobalSystemConfig(const BgpGlobalSystemConfig *new_config,
78 : BgpConfigManager::EventType event) {
79 0 : bool clear_peers = false;
80 :
81 0 : if (server_->global_config()->gr_enable() != new_config->gr_enable()) {
82 0 : server_->global_config()->set_gr_enable(new_config->gr_enable());
83 0 : clear_peers = true;
84 : }
85 0 : if (server_->global_config()->gr_time() != new_config->gr_time()) {
86 0 : server_->global_config()->set_gr_time(new_config->gr_time());
87 0 : clear_peers = true;
88 : }
89 0 : if (server_->global_config()->llgr_time() != new_config->llgr_time()) {
90 0 : server_->global_config()->set_llgr_time(new_config->llgr_time());
91 0 : clear_peers = true;
92 : }
93 0 : if (server_->global_config()->end_of_rib_timeout() !=
94 0 : new_config->end_of_rib_timeout()) {
95 0 : server_->global_config()->set_end_of_rib_timeout(
96 0 : new_config->end_of_rib_timeout());
97 0 : clear_peers = true;
98 : }
99 0 : if (server_->global_config()->gr_bgp_helper() !=
100 0 : new_config->gr_bgp_helper()) {
101 0 : server_->global_config()->set_gr_bgp_helper(
102 0 : new_config->gr_bgp_helper());
103 0 : clear_peers = true;
104 : }
105 0 : if (server_->global_config()->enable_4byte_as() !=
106 0 : new_config->enable_4byte_as()) {
107 0 : server_->global_config()->set_enable_4byte_as(
108 0 : new_config->enable_4byte_as());
109 0 : clear_peers = true;
110 : }
111 :
112 0 : if (server_->global_config()->fc_enabled() !=
113 0 : new_config->fc_enabled()) {
114 0 : server_->global_config()->set_fc_enabled(
115 0 : new_config->fc_enabled());
116 0 : clear_peers = true;
117 : }
118 :
119 0 : if (server_->global_config()->nh_check_enabled() !=
120 0 : new_config->nh_check_enabled()) {
121 0 : server_->global_config()->set_nh_check_enabled(
122 0 : new_config->nh_check_enabled());
123 0 : clear_peers = true;
124 : }
125 :
126 : // Clear peers if there's a change in always-compare-med knob.
127 0 : if (server_->global_config()->always_compare_med() !=
128 0 : new_config->always_compare_med()) {
129 0 : server_->global_config()->set_always_compare_med(
130 0 : new_config->always_compare_med());
131 0 : clear_peers = true;
132 : }
133 :
134 : // Process a change in rd-cluster-seed knob.
135 0 : if (server_->global_config()->rd_cluster_seed() !=
136 0 : new_config->rd_cluster_seed()) {
137 0 : server_->global_config()->set_rd_cluster_seed(
138 0 : new_config->rd_cluster_seed());
139 : }
140 :
141 : // Process a change in xmpp-hold-time knob.
142 0 : if (server_->global_config()->xmpp_hold_time() !=
143 0 : new_config->xmpp_hold_time()) {
144 0 : server_->global_config()->set_xmpp_hold_time(
145 0 : new_config->xmpp_hold_time());
146 : }
147 :
148 : // Process a change in all-tags-are-global knob.
149 0 : if (server_->global_config()->all_tags_are_global() !=
150 0 : new_config->all_tags_are_global()) {
151 0 : server_->global_config()->set_all_tags_are_global(
152 0 : new_config->all_tags_are_global());
153 : }
154 :
155 0 : bool clear_bgpaas_peers = false;
156 :
157 : // Clear bgpaas peers if there's a change in bgpaas-port-start.
158 0 : if (server_->global_config()->bgpaas_port_start() !=
159 0 : new_config->bgpaas_port_start()) {
160 0 : server_->global_config()->set_bgpaas_port_start(
161 0 : new_config->bgpaas_port_start());
162 0 : clear_bgpaas_peers = true;
163 : }
164 :
165 : // Clear bgpaas peers if there's a change in bgpaas-port-end.
166 0 : if (server_->global_config()->bgpaas_port_end() !=
167 0 : new_config->bgpaas_port_end()) {
168 0 : server_->global_config()->set_bgpaas_port_end(
169 0 : new_config->bgpaas_port_end());
170 0 : clear_bgpaas_peers = true;
171 : }
172 :
173 0 : if (clear_peers) {
174 0 : RoutingInstanceMgr *ri_mgr = server_->routing_instance_mgr();
175 0 : RoutingInstance *rti = ri_mgr->GetDefaultRoutingInstance();
176 0 : assert(rti);
177 0 : PeerManager *peer_manager = rti->LocatePeerManager();
178 0 : peer_manager->ClearAllPeers();
179 : }
180 :
181 0 : if (clear_peers || clear_bgpaas_peers)
182 0 : server_->ClearBgpaaSPeers();
183 0 : }
184 :
185 32 : void ProcessProtocolConfig(const BgpProtocolConfig *protocol_config,
186 : BgpConfigManager::EventType event) {
187 32 : const string &instance_name = protocol_config->instance_name();
188 :
189 : // We only support BGP sessions in master instance for now.
190 32 : if (instance_name != BgpConfigManager::kMasterInstance) {
191 0 : return;
192 : }
193 :
194 32 : if (event == BgpConfigManager::CFG_ADD ||
195 : event == BgpConfigManager::CFG_CHANGE) {
196 32 : BgpServerConfigUpdate(instance_name, protocol_config);
197 0 : } else if (event == BgpConfigManager::CFG_DELETE) {
198 0 : BgpServerConfigUpdate(instance_name, NULL);
199 : } else {
200 0 : assert(false);
201 : }
202 : }
203 :
204 32 : void BgpServerConfigUpdate(string instance_name,
205 : const BgpProtocolConfig *config) {
206 32 : boost::system::error_code ec;
207 32 : uint32_t config_identifier = 0;
208 32 : uint32_t config_autonomous_system = 0;
209 32 : uint32_t config_local_autonomous_system = 0;
210 32 : uint32_t config_hold_time = 0;
211 32 : uint32_t config_cluster_id = 0;
212 32 : bool config_admin_down = false;
213 32 : if (config) {
214 32 : config_admin_down = config->admin_down();
215 32 : config_identifier = config->identifier();
216 32 : config_autonomous_system = config->autonomous_system();
217 32 : config_local_autonomous_system = config->local_autonomous_system();
218 32 : config_cluster_id = config->cluster_id();
219 32 : config_hold_time = config->hold_time();
220 : }
221 :
222 32 : if (server_->admin_down_ != config_admin_down) {
223 0 : if (server_->admin_down_) {
224 0 : 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 0 : 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 0 : server_->admin_down_ = config_admin_down;
237 0 : if (server_->admin_down_)
238 0 : server_->NotifyAdminDown();
239 : }
240 :
241 : // We currently do not support bind failures or changes to listen port
242 : // in production mode.
243 32 : if (config && !server_->session_manager()->Initialize(config->port()) &&
244 0 : !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 32 : Ip4Address identifier(ntohl(config_identifier));
258 32 : if (server_->bgp_identifier_ != identifier) {
259 32 : if (!server_->bgp_identifier_.is_unspecified()) {
260 0 : 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 32 : 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 32 : server_->UpdateBgpIdentifier(identifier);
271 : }
272 :
273 32 : bool notify_asn_update = false;
274 32 : uint32_t old_asn = server_->autonomous_system_;
275 32 : uint32_t old_local_asn = server_->local_autonomous_system_;
276 32 : server_->autonomous_system_ = config_autonomous_system;
277 32 : if (config_local_autonomous_system) {
278 0 : server_->local_autonomous_system_ = config_local_autonomous_system;
279 : } else {
280 32 : server_->local_autonomous_system_ = config_autonomous_system;
281 : }
282 :
283 32 : if (server_->autonomous_system_ != old_asn) {
284 32 : if (old_asn != 0) {
285 0 : BGP_LOG_NOTICE_STR(BgpConfig, BGP_LOG_FLAG_SYSLOG,
286 : "Updated Autonomous System from " << old_asn <<
287 : " to " << server_->autonomous_system_);
288 : } else {
289 32 : 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 32 : notify_asn_update = true;
295 : }
296 :
297 32 : if (server_->local_autonomous_system_ != old_local_asn) {
298 32 : if (old_local_asn != 0) {
299 0 : 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 32 : 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 32 : notify_asn_update = true;
311 : }
312 :
313 32 : if (notify_asn_update) {
314 32 : server_->NotifyASNUpdate(old_asn, old_local_asn);
315 : }
316 :
317 32 : if (server_->hold_time_ != config_hold_time) {
318 0 : 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 0 : server_->hold_time_ = config_hold_time;
322 : }
323 :
324 32 : if (server_->cluster_id() != config_cluster_id) {
325 0 : 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 0 : server_->set_cluster_id(config_cluster_id);
329 0 : RoutingInstanceMgr *ri_mgr = server_->routing_instance_mgr();
330 0 : RoutingInstance *rti = ri_mgr->GetDefaultRoutingInstance();
331 0 : assert(rti);
332 0 : PeerManager *peer_manager = rti->LocatePeerManager();
333 0 : peer_manager->ClearAllInternalPeers();
334 : }
335 :
336 32 : ConnectionState::GetInstance()->Update();
337 32 : }
338 :
339 32 : void ProcessNeighborConfig(const BgpNeighborConfig *neighbor_config,
340 : BgpConfigManager::EventType event) {
341 32 : string instance_name = neighbor_config->instance_name();
342 32 : RoutingInstanceMgr *ri_mgr = server_->routing_instance_mgr();
343 32 : RoutingInstance *rti = ri_mgr->GetRoutingInstance(instance_name);
344 32 : if (!rti)
345 0 : return;
346 :
347 32 : if (event == BgpConfigManager::CFG_ADD ||
348 : event == BgpConfigManager::CFG_CHANGE) {
349 32 : if (rti->deleted())
350 0 : return;
351 32 : PeerManager *peer_manager = rti->LocatePeerManager();
352 32 : BgpPeer *peer = peer_manager->PeerLocate(server_, neighbor_config);
353 32 : if (peer) {
354 32 : server_->RemovePeer(peer->endpoint(), peer);
355 32 : peer->ConfigUpdate(neighbor_config);
356 32 : server_->InsertPeer(peer->endpoint(), peer);
357 : }
358 32 : } else if (event == BgpConfigManager::CFG_DELETE) {
359 0 : PeerManager *peer_manager = rti->peer_manager();
360 0 : if (!peer_manager)
361 0 : return;
362 0 : BgpPeer *peer = peer_manager->TriggerPeerDeletion(neighbor_config);
363 0 : if (peer) {
364 0 : server_->RemovePeer(peer->endpoint(), peer);
365 : }
366 : }
367 32 : }
368 :
369 0 : void ProcessRoutingPolicyConfig(const BgpRoutingPolicyConfig *policy_config,
370 : BgpConfigManager::EventType event) {
371 0 : RoutingPolicyMgr *mgr = server_->routing_policy_mgr();
372 0 : if (event == BgpConfigManager::CFG_ADD) {
373 0 : mgr->CreateRoutingPolicy(policy_config);
374 0 : } else if (event == BgpConfigManager::CFG_CHANGE) {
375 0 : mgr->UpdateRoutingPolicy(policy_config);
376 0 : } else if (event == BgpConfigManager::CFG_DELETE) {
377 0 : mgr->DeleteRoutingPolicy(policy_config->name());
378 : }
379 0 : }
380 :
381 384 : void ProcessInstanceConfig(const BgpInstanceConfig *instance_config,
382 : BgpConfigManager::EventType event) {
383 384 : RoutingInstanceMgr *mgr = server_->routing_instance_mgr();
384 384 : if (event == BgpConfigManager::CFG_ADD ||
385 : event == BgpConfigManager::CFG_CHANGE) {
386 384 : mgr->LocateRoutingInstance(instance_config->name());
387 0 : } else if (event == BgpConfigManager::CFG_DELETE) {
388 0 : mgr->DeleteRoutingInstance(instance_config->name());
389 : }
390 384 : }
391 :
392 : private:
393 : BgpServer *server_;
394 : };
395 :
396 : class BgpServer::DeleteActor : public LifetimeActor {
397 : public:
398 32 : explicit DeleteActor(BgpServer *server)
399 32 : : LifetimeActor(server->lifetime_manager()), server_(server) {
400 32 : }
401 32 : virtual bool MayDelete() const {
402 32 : CHECK_CONCURRENCY("bgp::Config");
403 32 : return server_->session_manager()->MayDelete();
404 : }
405 32 : virtual void Shutdown() {
406 32 : CHECK_CONCURRENCY("bgp::Config");
407 32 : server_->session_manager()->Shutdown();
408 32 : }
409 32 : virtual void Destroy() {
410 32 : CHECK_CONCURRENCY("bgp::Config");
411 32 : server_->config_manager()->Terminate();
412 32 : server_->session_manager()->Terminate();
413 32 : TcpServerManager::DeleteServer(server_->session_manager());
414 32 : server_->session_mgr_ = NULL;
415 32 : server_->set_destroyed();
416 32 : }
417 :
418 : private:
419 : BgpServer *server_;
420 : };
421 :
422 160 : bool BgpServer::IsDeleted() const {
423 160 : 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 5422 : bool BgpServer::IsReadyForDeletion() {
433 5422 : CHECK_CONCURRENCY("bgp::Config");
434 :
435 5422 : static TaskScheduler *scheduler = TaskScheduler::GetInstance();
436 5422 : static int db_table_task_id = scheduler->GetTaskId("db::DBTable");
437 : static int resolver_path_task_id =
438 5422 : scheduler->GetTaskId("bgp::ResolverPath");
439 : static int resolver_nexthop_task_id =
440 5422 : 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 10844 : if (!scheduler->IsTaskGroupEmpty(resolver_path_task_id) ||
446 5422 : !scheduler->IsTaskGroupEmpty(resolver_nexthop_task_id)) {
447 0 : return false;
448 : }
449 :
450 : // Check if the membership manager queue is empty.
451 5422 : if (!membership_mgr_->IsQueueEmpty()) {
452 335 : return false;
453 : }
454 :
455 : // Check if the Service Chain Manager Work Queues are empty.
456 5087 : if (!inet_service_chain_mgr_->IsQueueEmpty() ||
457 5087 : !inet6_service_chain_mgr_->IsQueueEmpty() ||
458 15261 : !evpn_service_chain_mgr_->IsQueueEmpty() ||
459 5087 : !evpn6_service_chain_mgr_->IsQueueEmpty()) {
460 0 : return false;
461 : }
462 :
463 : // Check if the DB requests queue and change list is empty.
464 5087 : if (!db_.IsDBQueueEmpty()) {
465 227 : 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 4860 : if (!rtarget_group_mgr_->IsRTargetRoutesProcessed()) {
472 0 : 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 4860 : if (!scheduler->IsTaskGroupEmpty(db_table_task_id)) {
479 99 : return false;
480 : }
481 :
482 4761 : return true;
483 : }
484 :
485 32 : BgpServer::BgpServer(EventManager *evm)
486 32 : : admin_down_(false),
487 32 : cluster_id_(0),
488 32 : autonomous_system_(0),
489 32 : local_autonomous_system_(0),
490 32 : bgp_identifier_(0),
491 32 : bgp_identifier_u32_(0),
492 32 : hold_time_(0),
493 32 : gr_helper_disable_(false),
494 32 : lifetime_manager_(BgpStaticObjectFactory::Create<BgpLifetimeManager>(this,
495 : TaskScheduler::GetInstance()->GetTaskId("bgp::Config"))),
496 32 : deleter_(new DeleteActor(this)),
497 32 : destroyed_(false),
498 32 : logging_disabled_(false),
499 32 : mvpn_ipv4_enable_(false),
500 32 : ignore_aspath_(false),
501 32 : aspath_db_(new AsPathDB(this)),
502 32 : aspath_4byte_db_(new AsPath4ByteDB(this)),
503 32 : as4path_db_(new As4PathDB(this)),
504 32 : olist_db_(new BgpOListDB(this)),
505 32 : cluster_list_db_(new ClusterListDB(this)),
506 32 : comm_db_(new CommunityDB(this)),
507 32 : edge_discovery_db_(new EdgeDiscoveryDB(this)),
508 32 : edge_forwarding_db_(new EdgeForwardingDB(this)),
509 32 : extcomm_db_(new ExtCommunityDB(this)),
510 32 : largecomm_db_(new LargeCommunityDB(this)),
511 32 : ovnpath_db_(new OriginVnPathDB(this)),
512 32 : pmsi_tunnel_db_(new PmsiTunnelDB(this)),
513 32 : attr_db_(new BgpAttrDB(this)),
514 32 : session_mgr_(BgpStaticObjectFactory::Create<BgpSessionManager>(evm, this)),
515 32 : update_sender_(new BgpUpdateSender(this)),
516 32 : inst_mgr_(BgpStaticObjectFactory::Create<RoutingInstanceMgr>(this)),
517 32 : policy_mgr_(BgpStaticObjectFactory::Create<RoutingPolicyMgr>(this)),
518 32 : rtarget_group_mgr_(BgpStaticObjectFactory::Create<RTargetGroupMgr>(this)),
519 32 : membership_mgr_(BgpStaticObjectFactory::Create<BgpMembershipManager>(this)),
520 32 : inet_condition_listener_(new BgpConditionListener(this)),
521 32 : inet6_condition_listener_(new BgpConditionListener(this)),
522 32 : evpn_condition_listener_(new BgpConditionListener(this)),
523 32 : evpn6_condition_listener_(new BgpConditionListener(this)),
524 32 : inetvpn_replicator_(new RoutePathReplicator(this, Address::INETVPN)),
525 32 : ermvpn_replicator_(new RoutePathReplicator(this, Address::ERMVPN)),
526 32 : mvpn_replicator_(new RoutePathReplicator(this, Address::MVPN)),
527 32 : evpn_replicator_(new RoutePathReplicator(this, Address::EVPN)),
528 32 : inet6vpn_replicator_(new RoutePathReplicator(this, Address::INET6VPN)),
529 32 : inet_service_chain_mgr_(
530 32 : BgpStaticObjectFactory::Create<IServiceChainMgr, SCAddress::INET>(this)),
531 32 : inet6_service_chain_mgr_(
532 32 : BgpStaticObjectFactory::Create<IServiceChainMgr, SCAddress::INET6>(this)),
533 32 : evpn_service_chain_mgr_(
534 32 : BgpStaticObjectFactory::Create<IServiceChainMgr, SCAddress::EVPN>(this)),
535 32 : evpn6_service_chain_mgr_(
536 32 : BgpStaticObjectFactory::Create<IServiceChainMgr, SCAddress::EVPN6>(this)),
537 32 : global_config_(new BgpGlobalSystemConfig()),
538 32 : global_qos_(new BgpGlobalQosConfig()),
539 32 : config_mgr_(BgpStaticObjectFactory::Create<BgpConfigManager>(this)),
540 96 : updater_(new ConfigUpdater(this)) {
541 32 : bgp_count_ = 0;
542 32 : num_up_peer_ = 0;
543 32 : deleting_count_ = 0;
544 32 : bgpaas_count_ = 0;
545 32 : num_up_bgpaas_peer_ = 0;
546 32 : deleting_bgpaas_count_ = 0;
547 32 : message_build_error_ = 0;
548 32 : }
549 :
550 32 : BgpServer::~BgpServer() {
551 32 : assert(deleting_count_ == 0);
552 32 : assert(deleting_bgpaas_count_ == 0);
553 32 : assert(srt_manager_list_.empty());
554 32 : }
555 :
556 2 : void BgpServer::Initialize() {
557 2 : RibOutUpdates::Initialize();
558 2 : }
559 :
560 1 : void BgpServer::Terminate() {
561 1 : RibOutUpdates::Terminate();
562 1 : }
563 :
564 0 : string BgpServer::ToString() const {
565 0 : return bgp_identifier_.to_string();
566 : }
567 :
568 32 : void BgpServer::Shutdown() {
569 32 : deleter_->Delete();
570 32 : }
571 :
572 192 : LifetimeActor *BgpServer::deleter() {
573 192 : return deleter_.get();
574 : }
575 :
576 0 : bool BgpServer::HasSelfConfiguration() const {
577 0 : if (!bgp_identifier_u32())
578 0 : return false;
579 0 : if (!local_autonomous_system())
580 0 : return false;
581 0 : if (!autonomous_system())
582 0 : return false;
583 0 : return true;
584 : }
585 :
586 80 : int BgpServer::RegisterPeer(BgpPeer *peer) {
587 80 : CHECK_CONCURRENCY("bgp::Config");
588 :
589 80 : if (peer->IsRouterTypeBGPaaS()) {
590 0 : bgpaas_count_++;
591 : } else {
592 80 : bgp_count_++;
593 : }
594 :
595 80 : BgpPeerList::iterator loc;
596 : bool result;
597 80 : tie(loc, result) = peer_list_.insert(make_pair(peer->peer_name(), peer));
598 80 : assert(result);
599 80 : assert(loc->second == peer);
600 :
601 80 : size_t bit = peer_bmap_.find_first();
602 80 : if (bit == peer_bmap_.npos) {
603 80 : bit = peer_bmap_.size();
604 80 : peer_bmap_.resize(bit + 1, true);
605 : }
606 80 : peer_bmap_.reset(bit);
607 80 : return bit;
608 : }
609 :
610 80 : void BgpServer::UnregisterPeer(BgpPeer *peer) {
611 80 : CHECK_CONCURRENCY("bgp::Config");
612 :
613 80 : if (peer->IsRouterTypeBGPaaS()) {
614 0 : assert(bgpaas_count_);
615 0 : bgpaas_count_--;
616 : } else {
617 80 : assert(bgp_count_);
618 80 : bgp_count_--;
619 : }
620 :
621 80 : BgpPeerList::iterator loc = peer_list_.find(peer->peer_name());
622 80 : assert(loc != peer_list_.end());
623 80 : peer_list_.erase(loc);
624 :
625 80 : peer_bmap_.set(peer->GetIndex());
626 160 : for (size_t i = peer_bmap_.size(); i != 0; i--) {
627 128 : if (peer_bmap_[i-1] != true) {
628 48 : if (i != peer_bmap_.size()) {
629 17 : peer_bmap_.resize(i);
630 : }
631 48 : return;
632 : }
633 : }
634 32 : peer_bmap_.clear();
635 : }
636 :
637 0 : BgpPeer *BgpServer::FindPeer(const string &name) {
638 0 : BgpPeerList::iterator loc = peer_list_.find(name);
639 0 : return (loc != peer_list_.end() ? loc->second : NULL);
640 : }
641 :
642 0 : BgpPeer *BgpServer::FindNextPeer(const string &name) {
643 0 : BgpPeerList::iterator loc = peer_list_.upper_bound(name);
644 0 : return (loc != peer_list_.end() ? loc->second : NULL);
645 : }
646 :
647 32 : void BgpServer::InsertPeer(TcpSession::Endpoint remote, BgpPeer *peer) {
648 32 : if (!remote.port() && remote.address().is_unspecified())
649 32 : return;
650 0 : endpoint_peer_list_.insert(make_pair(remote, peer));
651 : }
652 :
653 32 : void BgpServer::RemovePeer(TcpSession::Endpoint remote, BgpPeer *peer) {
654 32 : EndpointPeerList::iterator loc = endpoint_peer_list_.lower_bound(remote);
655 32 : while (loc != endpoint_peer_list_.end() && loc->first == remote) {
656 0 : if (loc->second == peer) {
657 0 : endpoint_peer_list_.erase(loc);
658 0 : break;
659 : }
660 0 : ++loc;
661 : }
662 32 : }
663 :
664 0 : void BgpServer::ClearBgpaaSPeers() {
665 0 : for (auto &i : endpoint_peer_list_) {
666 0 : i.second->Clear(BgpProto::Notification::OtherConfigChange);
667 : }
668 0 : }
669 :
670 0 : BgpPeer *BgpServer::FindPeer(TcpSession::Endpoint remote) const {
671 0 : EndpointPeerList::const_iterator loc = endpoint_peer_list_.find(remote);
672 0 : return (loc == endpoint_peer_list_.end() ? NULL : loc->second);
673 : }
674 :
675 0 : BgpPeer *BgpServer::FindExactPeer(const BgpPeer *peer) const {
676 : EndpointPeerList::const_iterator loc =
677 0 : endpoint_peer_list_.lower_bound(peer->endpoint());
678 0 : while (loc != endpoint_peer_list_.end() && loc->first == peer->endpoint()) {
679 0 : if (loc->second == peer)
680 0 : return loc->second;
681 0 : ++loc;
682 : }
683 0 : return NULL;
684 : }
685 :
686 1823 : const string &BgpServer::localname() const {
687 1823 : return config_mgr_->localname();
688 : }
689 :
690 2160 : boost::asio::io_context *BgpServer::ioservice() {
691 2160 : 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 220 : bool BgpServer::IsNextHopCheckEnabled() const {
699 220 : if (!global_config_->fc_enabled())
700 220 : return false;
701 0 : return (global_config_->nh_check_enabled());
702 : }
703 :
704 0 : uint16_t BgpServer::GetGracefulRestartTime() const {
705 0 : if (!global_config_->gr_enable())
706 0 : return 0;
707 0 : return global_config_->gr_time();
708 : }
709 :
710 0 : uint32_t BgpServer::GetLongLivedGracefulRestartTime() const {
711 0 : if (!global_config_->gr_enable())
712 0 : return 0;
713 0 : return global_config_->llgr_time();
714 : }
715 :
716 0 : uint16_t BgpServer::GetXmppHoldTime() const {
717 0 : if (!global_config_->fc_enabled())
718 0 : return XMPP_HOLD_TIME_DEFAULT;
719 0 : return global_config_->xmpp_hold_time();
720 : }
721 :
722 144 : uint32_t BgpServer::GetEndOfRibReceiveTime() const {
723 144 : return global_config_->end_of_rib_timeout();
724 : }
725 :
726 48 : uint32_t BgpServer::GetEndOfRibSendTime() const {
727 48 : return global_config_->end_of_rib_timeout();
728 : }
729 :
730 48 : bool BgpServer::IsServerStartingUp() const {
731 48 : return MiscUtils::GetUpTimeSeconds() < 0.20 * GetEndOfRibSendTime();
732 : }
733 :
734 198 : bool BgpServer::enable_4byte_as() const {
735 198 : return global_config()->enable_4byte_as();
736 : }
737 :
738 16 : void BgpServer::set_enable_4byte_as(bool flag) {
739 16 : global_config()->set_enable_4byte_as(flag);
740 16 : }
741 :
742 96 : bool BgpServer::IsGRHelperModeEnabled() const {
743 :
744 : // Check if disabled in .conf file.
745 96 : if (gr_helper_disable_)
746 0 : return false;
747 :
748 : // Check if GR is disabled..
749 96 : if (!global_config_->gr_enable())
750 96 : return false;
751 :
752 : // Check from configuration.
753 0 : return global_config_->gr_bgp_helper();
754 : }
755 :
756 0 : uint32_t BgpServer::num_routing_instance() const {
757 0 : assert(inst_mgr_.get());
758 0 : return inst_mgr_->count();
759 : }
760 :
761 0 : uint32_t BgpServer::num_deleted_routing_instance() const {
762 0 : assert(inst_mgr_.get());
763 0 : return inst_mgr_->deleted_count();
764 : }
765 :
766 0 : uint32_t BgpServer::get_output_queue_depth() const {
767 0 : uint32_t out_q_depth = 0;
768 0 : for (RoutingInstanceMgr::RoutingInstanceIterator rit = inst_mgr_->begin();
769 0 : rit != inst_mgr_->end(); ++rit) {
770 : RoutingInstance::RouteTableList const rt_list =
771 0 : rit->second->GetTables();
772 0 : for (RoutingInstance::RouteTableList::const_iterator it =
773 0 : rt_list.begin(); it != rt_list.end(); ++it) {
774 0 : BgpTable *table = it->second;
775 : size_t markers;
776 0 : out_q_depth += table->GetPendingRiboutsCount(&markers);
777 : }
778 0 : }
779 0 : return out_q_depth;
780 : }
781 :
782 0 : uint32_t BgpServer::num_service_chains() const {
783 0 : return inet_service_chain_mgr_->PendingQueueSize() +
784 0 : inet_service_chain_mgr_->ResolvedQueueSize() +
785 0 : inet6_service_chain_mgr_->PendingQueueSize() +
786 0 : inet6_service_chain_mgr_->ResolvedQueueSize() +
787 0 : evpn_service_chain_mgr_->PendingQueueSize() +
788 0 : evpn_service_chain_mgr_->ResolvedQueueSize() +
789 0 : evpn6_service_chain_mgr_->PendingQueueSize() +
790 0 : evpn6_service_chain_mgr_->ResolvedQueueSize();
791 : }
792 :
793 0 : uint32_t BgpServer::num_down_service_chains() const {
794 0 : return inet_service_chain_mgr_->PendingQueueSize() +
795 0 : inet_service_chain_mgr_->GetDownServiceChainCount() +
796 0 : inet6_service_chain_mgr_->PendingQueueSize() +
797 0 : inet6_service_chain_mgr_->GetDownServiceChainCount() +
798 0 : evpn_service_chain_mgr_->PendingQueueSize() +
799 0 : evpn_service_chain_mgr_->GetDownServiceChainCount() +
800 0 : evpn6_service_chain_mgr_->PendingQueueSize() +
801 0 : evpn6_service_chain_mgr_->GetDownServiceChainCount();
802 : }
803 :
804 0 : uint32_t BgpServer::num_static_routes() const {
805 0 : return GetStaticRouteCount();
806 : }
807 :
808 0 : uint32_t BgpServer::num_down_static_routes() const {
809 0 : return GetDownStaticRouteCount();
810 : }
811 :
812 0 : void BgpServer::VisitBgpPeers(BgpServer::VisitorFn fn) const {
813 0 : for (BgpPeerList::const_iterator loc = peer_list_.begin();
814 0 : loc != peer_list_.end(); ++loc) {
815 0 : fn(loc->second);
816 : }
817 0 : }
818 :
819 0 : int BgpServer::RegisterAdminDownCallback(AdminDownCb callback) {
820 0 : tbb::spin_rw_mutex::scoped_lock write_lock(rw_mutex_, true);
821 0 : size_t i = admin_down_bmap_.find_first();
822 0 : if (i == admin_down_bmap_.npos) {
823 0 : i = admin_down_listeners_.size();
824 0 : 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 0 : return i;
833 0 : }
834 :
835 0 : void BgpServer::UnregisterAdminDownCallback(int listener) {
836 0 : tbb::spin_rw_mutex::scoped_lock write_lock(rw_mutex_, true);
837 0 : admin_down_listeners_[listener] = NULL;
838 0 : if ((size_t) listener == admin_down_listeners_.size() - 1) {
839 0 : while (!admin_down_listeners_.empty() &&
840 0 : admin_down_listeners_.back() == NULL) {
841 0 : admin_down_listeners_.pop_back();
842 : }
843 0 : 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 0 : }
853 :
854 0 : void BgpServer::NotifyAdminDown() {
855 0 : tbb::spin_rw_mutex::scoped_lock read_lock(rw_mutex_, false);
856 0 : for (AdminDownListenersList::iterator iter = admin_down_listeners_.begin();
857 0 : iter != admin_down_listeners_.end(); ++iter) {
858 0 : if (*iter != NULL) {
859 0 : AdminDownCb cb = *iter;
860 0 : (cb)();
861 0 : }
862 : }
863 0 : }
864 :
865 32 : int BgpServer::RegisterASNUpdateCallback(ASNUpdateCb callback) {
866 32 : tbb::spin_rw_mutex::scoped_lock write_lock(rw_mutex_, true);
867 32 : size_t i = asn_bmap_.find_first();
868 32 : if (i == asn_bmap_.npos) {
869 32 : i = asn_listeners_.size();
870 32 : asn_listeners_.push_back(callback);
871 : } else {
872 0 : asn_bmap_.reset(i);
873 0 : if (asn_bmap_.none()) {
874 0 : asn_bmap_.clear();
875 : }
876 0 : asn_listeners_[i] = callback;
877 : }
878 32 : return i;
879 32 : }
880 :
881 32 : void BgpServer::UnregisterASNUpdateCallback(int listener) {
882 32 : tbb::spin_rw_mutex::scoped_lock write_lock(rw_mutex_, true);
883 32 : asn_listeners_[listener] = NULL;
884 32 : if ((size_t) listener == asn_listeners_.size() - 1) {
885 64 : while (!asn_listeners_.empty() && asn_listeners_.back() == NULL) {
886 32 : asn_listeners_.pop_back();
887 : }
888 32 : if (asn_bmap_.size() > asn_listeners_.size()) {
889 0 : asn_bmap_.resize(asn_listeners_.size());
890 : }
891 : } else {
892 0 : if ((size_t) listener >= asn_bmap_.size()) {
893 0 : asn_bmap_.resize(listener + 1);
894 : }
895 0 : asn_bmap_.set(listener);
896 : }
897 32 : }
898 :
899 32 : void BgpServer::NotifyASNUpdate(as_t old_asn, as_t old_local_asn) {
900 32 : tbb::spin_rw_mutex::scoped_lock read_lock(rw_mutex_, false);
901 32 : for (ASNUpdateListenersList::iterator iter = asn_listeners_.begin();
902 64 : iter != asn_listeners_.end(); ++iter) {
903 32 : if (*iter != NULL) {
904 32 : ASNUpdateCb cb = *iter;
905 32 : (cb)(old_asn, old_local_asn);
906 32 : }
907 : }
908 32 : }
909 :
910 80 : int BgpServer::RegisterDSCPUpdateCallback(DSCPUpdateCb callback) {
911 80 : tbb::spin_rw_mutex::scoped_lock write_lock(rw_mutex_, true);
912 80 : size_t i = dscp_bmap_.find_first();
913 80 : if (i == dscp_bmap_.npos) {
914 80 : i = dscp_listeners_.size();
915 80 : dscp_listeners_.push_back(callback);
916 : } else {
917 0 : dscp_bmap_.reset(i);
918 0 : if (dscp_bmap_.none()) {
919 0 : dscp_bmap_.clear();
920 : }
921 0 : dscp_listeners_[i] = callback;
922 : }
923 80 : return i;
924 80 : }
925 :
926 80 : void BgpServer::UnregisterDSCPUpdateCallback(int listener) {
927 80 : tbb::spin_rw_mutex::scoped_lock write_lock(rw_mutex_, true);
928 80 : dscp_listeners_[listener] = NULL;
929 80 : if ((size_t) listener == dscp_listeners_.size() - 1) {
930 129 : while (!dscp_listeners_.empty() && dscp_listeners_.back() == NULL) {
931 80 : dscp_listeners_.pop_back();
932 : }
933 49 : if (dscp_bmap_.size() > dscp_listeners_.size()) {
934 31 : dscp_bmap_.resize(dscp_listeners_.size());
935 : }
936 : } else {
937 31 : if ((size_t) listener >= dscp_bmap_.size()) {
938 28 : dscp_bmap_.resize(listener + 1);
939 : }
940 31 : dscp_bmap_.set(listener);
941 : }
942 80 : }
943 :
944 0 : void BgpServer::NotifyDSCPUpdate(int new_dscp_value) {
945 0 : tbb::spin_rw_mutex::scoped_lock read_lock(rw_mutex_, false);
946 0 : for (DSCPUpdateListenersList::iterator iter = dscp_listeners_.begin();
947 0 : iter != dscp_listeners_.end(); ++iter) {
948 0 : if (*iter != NULL) {
949 0 : DSCPUpdateCb cb = *iter;
950 0 : (cb)(new_dscp_value);
951 0 : }
952 : }
953 0 : }
954 :
955 128 : int BgpServer::RegisterIdentifierUpdateCallback(IdentifierUpdateCb callback) {
956 128 : tbb::spin_rw_mutex::scoped_lock write_lock(rw_mutex_, true);
957 128 : size_t i = id_bmap_.find_first();
958 128 : if (i == id_bmap_.npos) {
959 128 : i = id_listeners_.size();
960 128 : 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 128 : return i;
969 128 : }
970 :
971 128 : void BgpServer::UnregisterIdentifierUpdateCallback(int listener) {
972 128 : tbb::spin_rw_mutex::scoped_lock write_lock(rw_mutex_, true);
973 128 : id_listeners_[listener] = NULL;
974 128 : if ((size_t) listener == id_listeners_.size() - 1) {
975 192 : while (!id_listeners_.empty() && id_listeners_.back() == NULL) {
976 128 : id_listeners_.pop_back();
977 : }
978 64 : if (id_bmap_.size() > id_listeners_.size()) {
979 64 : id_bmap_.resize(id_listeners_.size());
980 : }
981 : } else {
982 64 : if ((size_t) listener >= id_bmap_.size()) {
983 37 : id_bmap_.resize(listener + 1);
984 : }
985 64 : id_bmap_.set(listener);
986 : }
987 128 : }
988 :
989 32 : void BgpServer::NotifyIdentifierUpdate(Ip4Address old_identifier) {
990 32 : tbb::spin_rw_mutex::scoped_lock read_lock(rw_mutex_, false);
991 32 : for (IdentifierUpdateListenersList::iterator iter = id_listeners_.begin();
992 64 : iter != id_listeners_.end(); ++iter) {
993 32 : if (*iter != NULL) {
994 32 : IdentifierUpdateCb cb = *iter;
995 32 : (cb)(old_identifier);
996 32 : }
997 : }
998 32 : }
999 :
1000 0 : void BgpServer::InsertStaticRouteMgr(IStaticRouteMgr *srt_manager) {
1001 0 : CHECK_CONCURRENCY("bgp::Config", "bgp::ConfigHelper");
1002 0 : tbb::spin_rw_mutex::scoped_lock write_lock(rw_mutex_, true);
1003 0 : srt_manager_list_.insert(srt_manager);
1004 0 : }
1005 :
1006 0 : void BgpServer::RemoveStaticRouteMgr(IStaticRouteMgr *srt_manager) {
1007 0 : CHECK_CONCURRENCY("bgp::Config", "bgp::ConfigHelper");
1008 0 : tbb::spin_rw_mutex::scoped_lock write_lock(rw_mutex_, true);
1009 0 : srt_manager_list_.erase(srt_manager);
1010 0 : }
1011 :
1012 576 : void BgpServer::NotifyAllStaticRoutes() {
1013 576 : CHECK_CONCURRENCY("bgp::Config", "bgp::ConfigHelper");
1014 576 : tbb::spin_rw_mutex::scoped_lock write_lock(rw_mutex_, true);
1015 576 : for (StaticRouteMgrList::iterator it = srt_manager_list_.begin();
1016 576 : it != srt_manager_list_.end(); ++it) {
1017 0 : IStaticRouteMgr *srt_manager = *it;
1018 0 : srt_manager->NotifyAllRoutes();
1019 : }
1020 576 : }
1021 :
1022 0 : uint32_t BgpServer::GetStaticRouteCount() const {
1023 0 : CHECK_CONCURRENCY("bgp::ShowCommand");
1024 0 : uint32_t count = 0;
1025 0 : for (StaticRouteMgrList::iterator it = srt_manager_list_.begin();
1026 0 : it != srt_manager_list_.end(); ++it) {
1027 0 : IStaticRouteMgr *srt_manager = *it;
1028 0 : count += srt_manager->GetRouteCount();
1029 : }
1030 0 : return count;
1031 : }
1032 :
1033 0 : uint32_t BgpServer::GetDownStaticRouteCount() const {
1034 0 : CHECK_CONCURRENCY("bgp::ShowCommand");
1035 0 : uint32_t count = 0;
1036 0 : for (StaticRouteMgrList::iterator it = srt_manager_list_.begin();
1037 0 : it != srt_manager_list_.end(); ++it) {
1038 0 : IStaticRouteMgr *srt_manager = *it;
1039 0 : count += srt_manager->GetDownRouteCount();
1040 : }
1041 0 : return count;
1042 : }
1043 :
1044 0 : void BgpServer::FillPeerStats(const BgpPeer *peer) const {
1045 0 : PeerStatsInfo stats;
1046 0 : PeerStats::FillPeerDebugStats(peer->peer_stats(), &stats);
1047 :
1048 0 : BgpPeerInfoData peer_info;
1049 0 : peer_info.set_name(peer->ToUVEKey());
1050 0 : peer_info.set_peer_stats_info(stats);
1051 0 : assert(!peer_info.get_name().empty());
1052 0 : BGP_UVE_SEND(BGPPeerInfo, peer_info);
1053 :
1054 0 : PeerStatsData peer_stats_data;
1055 0 : peer_stats_data.set_name(peer->ToUVEKey());
1056 0 : peer_stats_data.set_encoding("BGP");
1057 0 : PeerStats::FillPeerUpdateStats(peer->peer_stats(), &peer_stats_data);
1058 0 : assert(!peer_stats_data.get_name().empty());
1059 0 : BGP_UVE_SEND2(PeerStatsUve, peer_stats_data, "ObjectBgpPeer");
1060 :
1061 0 : PeerFlapInfo flap_info;
1062 0 : flap_info.set_flap_count(peer->flap_count());
1063 0 : flap_info.set_flap_time(peer->last_flap());
1064 :
1065 0 : PeerFlapData peer_flap_data;
1066 0 : peer_flap_data.set_name(peer->ToUVEKey());
1067 0 : peer_flap_data.set_encoding("BGP");
1068 0 : peer_flap_data.set_flap_info(flap_info);
1069 0 : assert(!peer_flap_data.get_name().empty());
1070 0 : BGP_UVE_SEND2(PeerFlap, peer_flap_data, "ObjectBgpPeer");
1071 0 : }
1072 :
1073 0 : bool BgpServer::CollectStats(BgpRouterState *state, bool first) const {
1074 0 : CHECK_CONCURRENCY("bgp::ShowCommand");
1075 :
1076 0 : VisitBgpPeers(boost::bind(&BgpServer::FillPeerStats, this, _1));
1077 0 : bool change = false;
1078 0 : uint32_t is_admin_down = admin_down();
1079 0 : if (first || is_admin_down != state->get_admin_down()) {
1080 0 : state->set_admin_down(is_admin_down);
1081 0 : change = true;
1082 : }
1083 :
1084 0 : string router_id = bgp_identifier_string();
1085 0 : if (first || router_id != state->get_router_id()) {
1086 0 : state->set_router_id(router_id);
1087 0 : change = true;
1088 : }
1089 :
1090 0 : uint32_t local_asn = local_autonomous_system();
1091 0 : if (first || local_asn != state->get_local_asn()) {
1092 0 : state->set_local_asn(local_asn);
1093 0 : change = true;
1094 : }
1095 :
1096 0 : uint32_t global_asn = autonomous_system();
1097 0 : if (first || global_asn != state->get_global_asn()) {
1098 0 : state->set_global_asn(global_asn);
1099 0 : change = true;
1100 : }
1101 :
1102 0 : uint32_t num_bgp = num_bgp_peer();
1103 0 : if (first || num_bgp != state->get_num_bgp_peer()) {
1104 0 : state->set_num_bgp_peer(num_bgp);
1105 0 : change = true;
1106 : }
1107 :
1108 0 : uint32_t num_up_bgp_peer = NumUpPeer();
1109 0 : if (first || num_up_bgp_peer != state->get_num_up_bgp_peer()) {
1110 0 : state->set_num_up_bgp_peer(num_up_bgp_peer);
1111 0 : change = true;
1112 : }
1113 :
1114 0 : uint32_t deleting_bgp_peer = num_deleting_bgp_peer();
1115 0 : if (first || deleting_bgp_peer != state->get_num_deleting_bgp_peer()) {
1116 0 : state->set_num_deleting_bgp_peer(deleting_bgp_peer);
1117 0 : change = true;
1118 : }
1119 :
1120 0 : uint32_t num_bgpaas = num_bgpaas_peer();
1121 0 : if (first || num_bgpaas != state->get_num_bgpaas_peer()) {
1122 0 : state->set_num_bgpaas_peer(num_bgpaas);
1123 0 : change = true;
1124 : }
1125 :
1126 0 : uint32_t num_up_bgpaas_peer = NumUpBgpaasPeer();
1127 0 : if (first || num_up_bgpaas_peer != state->get_num_up_bgpaas_peer()) {
1128 0 : state->set_num_up_bgpaas_peer(num_up_bgpaas_peer);
1129 0 : change = true;
1130 : }
1131 :
1132 0 : uint32_t deleting_bgpaas_peer = num_deleting_bgpaas_peer();
1133 0 : if (first || deleting_bgpaas_peer !=
1134 0 : state->get_num_deleting_bgpaas_peer()) {
1135 0 : state->set_num_deleting_bgpaas_peer(deleting_bgpaas_peer);
1136 0 : change = true;
1137 : }
1138 :
1139 0 : uint32_t num_ri = num_routing_instance();
1140 0 : if (first || num_ri != state->get_num_routing_instance()) {
1141 0 : state->set_num_routing_instance(num_ri);
1142 0 : change = true;
1143 : }
1144 :
1145 0 : uint32_t num_deleted_ri = num_deleted_routing_instance();
1146 0 : if (first || num_deleted_ri != state->get_num_deleted_routing_instance()) {
1147 0 : state->set_num_deleted_routing_instance(num_deleted_ri);
1148 0 : change = true;
1149 : }
1150 :
1151 0 : uint32_t service_chains = num_service_chains();
1152 0 : if (first || service_chains != state->get_num_service_chains()) {
1153 0 : state->set_num_service_chains(service_chains);
1154 0 : change = true;
1155 : }
1156 :
1157 0 : uint32_t down_service_chains = num_down_service_chains();
1158 0 : if (first || down_service_chains != state->get_num_down_service_chains()) {
1159 0 : state->set_num_down_service_chains(down_service_chains);
1160 0 : change = true;
1161 : }
1162 :
1163 0 : uint32_t static_routes = num_static_routes();
1164 0 : if (first || static_routes != state->get_num_static_routes()) {
1165 0 : state->set_num_static_routes(static_routes);
1166 0 : change = true;
1167 : }
1168 :
1169 0 : uint32_t down_static_routes = num_down_static_routes();
1170 0 : if (first || down_static_routes != state->get_num_down_static_routes()) {
1171 0 : state->set_num_down_static_routes(down_static_routes);
1172 0 : change = true;
1173 : }
1174 :
1175 0 : uint32_t out_load = inst_mgr_->SendTableStatsUve();
1176 0 : if (first || out_load != state->get_output_queue_depth()) {
1177 0 : state->set_output_queue_depth(out_load);
1178 0 : change = true;
1179 : }
1180 :
1181 0 : vector<string> bgp_config_peer_list;
1182 0 : BOOST_FOREACH(BgpConfigManager::NeighborMap::value_type value,
1183 : config_mgr_->NeighborMapItems(BgpConfigManager::kMasterInstance)) {
1184 0 : const BgpNeighborConfig *neighbor = value.second;
1185 0 : string name(BgpConfigManager::kMasterInstance);
1186 0 : name += ":";
1187 0 : name += localname();
1188 0 : name += ":";
1189 0 : name += neighbor->name();
1190 0 : bgp_config_peer_list.push_back(name);
1191 0 : }
1192 0 : sort(bgp_config_peer_list.begin(), bgp_config_peer_list.end());
1193 0 : if (first || bgp_config_peer_list != state->get_bgp_config_peer_list()) {
1194 0 : state->set_bgp_config_peer_list(bgp_config_peer_list);
1195 0 : change = true;
1196 : }
1197 :
1198 0 : vector<string> bgp_oper_peer_list;
1199 0 : const RoutingInstance *rtinstance = inst_mgr_->GetDefaultRoutingInstance();
1200 0 : const PeerManager *peer_manager = rtinstance->peer_manager();
1201 0 : for (const BgpPeer *peer = peer_manager->NextPeer(BgpPeerKey());
1202 0 : peer != NULL; peer = peer_manager->NextPeer(peer->peer_key())) {
1203 0 : bgp_oper_peer_list.push_back(peer->ToUVEKey());
1204 : }
1205 0 : sort(bgp_oper_peer_list.begin(), bgp_oper_peer_list.end());
1206 0 : if (first || bgp_oper_peer_list != state->get_bgp_oper_peer_list()) {
1207 0 : state->set_bgp_oper_peer_list(bgp_oper_peer_list);
1208 0 : change = true;
1209 : }
1210 :
1211 0 : return change;
1212 0 : }
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 32 : void BgpServer::UpdateBgpIdentifier(const Ip4Address &identifier) {
1222 32 : Ip4Address old_identifier = bgp_identifier_;
1223 32 : bgp_identifier_ = identifier;
1224 32 : bgp_identifier_u32_ = identifier.to_ulong();
1225 32 : NotifyIdentifierUpdate(old_identifier);
1226 32 : }
|