OpenSDN source code
bgp_peer.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3  */
4 
5 #include "bgp/bgp_peer.h"
6 
7 #include <algorithm>
8 #include <limits>
9 #include <map>
10 
11 #include <boost/assign/list_of.hpp>
12 #include <boost/foreach.hpp>
13 #include <boost/tuple/tuple.hpp>
14 
15 #include "base/set_util.h"
16 #include "base/task_annotations.h"
17 #include "bgp/bgp_factory.h"
18 #include "bgp/bgp_log.h"
19 #include "bgp/bgp_membership.h"
20 #include "bgp/bgp_peer_close.h"
21 #include "bgp/bgp_sandesh.h"
22 #include "bgp/bgp_server.h"
23 #include "bgp/bgp_session.h"
25 #include "bgp/bgp_peer_types.h"
26 #include "bgp/community.h"
28 #include "bgp/evpn/evpn_table.h"
29 #include "bgp/inet/inet_table.h"
30 #include "bgp/inet6/inet6_table.h"
33 #include "bgp/mvpn/mvpn_table.h"
34 #include "bgp/peer_close_manager.h"
42 using boost::assign::list_of;
43 using boost::assign::map_list_of;
44 using boost::system::error_code;
45 using boost::tie;
46 using std::copy;
47 using std::dec;
48 using std::map;
49 using std::numeric_limits;
50 using std::ostringstream;
51 using std::string;
52 using std::vector;
53 
55 public:
56  explicit PeerStats(BgpPeer *peer)
57  : peer_(peer) {
58  }
59 
60  // Used when peer flaps.
61  // Reset all counters.
62  // Socket counters are implicitly cleared because we use a new socket.
63  virtual void Clear() {
65  proto_stats_[0] = ProtoStats();
66  proto_stats_[1] = ProtoStats();
69  }
70 
71  // Printable name
72  virtual string ToString() const {
73  return peer_->ToString();
74  }
75  // Previous State of the peer
76  virtual string last_state() const {
77  return peer_->state_machine()->LastStateName();
78  }
79  virtual string last_state_change_at() const {
81  }
82  // Last error on this peer
83  virtual string last_error() const {
85  }
86  // Last Event on this peer
87  virtual string last_event() const {
88  return peer_->state_machine()->last_event();
89  }
90 
91  // When was the Last
92  virtual string last_flap() const {
93  return peer_->last_flap_at();
94  }
95 
96  // Total number of flaps
97  virtual uint64_t num_flaps() const {
98  return peer_->flap_count();
99  }
100 
101  virtual void GetRxProtoStats(ProtoStats *stats) const {
102  *stats = proto_stats_[0];
103  }
104 
105  virtual void GetTxProtoStats(ProtoStats *stats) const {
106  *stats = proto_stats_[1];
107  }
108 
109  virtual void GetRxRouteUpdateStats(UpdateStats *stats) const {
110  *stats = update_stats_[0];
111  }
112 
113  virtual void GetTxRouteUpdateStats(UpdateStats *stats) const {
114  *stats = update_stats_[1];
115  }
116 
117  virtual void GetRxSocketStats(IPeerDebugStats::SocketStats *stats) const {
118  if (peer_->session()) {
119  const io::SocketStats &socket_stats = peer_->session()->GetSocketStats();
120  stats->calls = socket_stats.read_calls;
121  stats->bytes = socket_stats.read_bytes;
122  }
123  }
124 
125  virtual void GetTxSocketStats(IPeerDebugStats::SocketStats *stats) const {
126  if (peer_->session()) {
127  const io::SocketStats &socket_stats = peer_->session()->GetSocketStats();
128  stats->calls = socket_stats.write_calls;
129  stats->bytes = socket_stats.write_bytes;
130  stats->blocked_count = socket_stats.write_blocked;
131  stats->blocked_duration_usecs =
132  socket_stats.write_blocked_duration_usecs;
133  }
134  }
135 
136  virtual void UpdateTxUnreachRoute(uint64_t count) {
137  update_stats_[1].unreach += count;
138  }
139 
140  virtual void UpdateTxReachRoute(uint64_t count) {
141  update_stats_[1].reach += count;
142  }
143 
144  // Do nothing for bgp peers.
145  virtual void GetRxErrorStats(RxErrorStats *stats) const {
146  }
147 
148  virtual void GetRxRouteStats(RxRouteStats *stats) const {
151  }
152 
153 private:
154  friend class BgpPeer;
155 
160 };
161 
163 public:
164  explicit DeleteActor(BgpPeer *peer)
165  : LifetimeActor(peer->server_->lifetime_manager()),
166  peer_(peer) {
167  }
168 
169  virtual bool MayDelete() const {
170  CHECK_CONCURRENCY("bgp::Config");
171  if (!peer_->close_manager_->IsQueueEmpty())
172  return false;
173  if (peer_->IsCloseInProgress())
174  return false;
175  if (!peer_->state_machine_->IsQueueEmpty())
176  return false;
178  return false;
179  return true;
180  }
181 
182  virtual void Shutdown() {
183  CHECK_CONCURRENCY("bgp::Config");
185  }
186 
187  virtual void Destroy() {
188  CHECK_CONCURRENCY("bgp::Config");
190  if (peer_->IsRouterTypeBGPaaS()) {
192  } else {
194  }
195  if (peer_->dscp_listener_id_ >= 0) {
198  peer_->dscp_listener_id_ = -1;
199  }
200  if (peer_->instance_op_ >= 0) {
202  UnregisterInstanceOpCallback(peer_->instance_op_);
203  peer_->instance_op_ = -1;
204  }
205  if (peer_->asn_listener_id_ >= 0) {
208  peer_->asn_listener_id_ = -1;
209  }
210  assert(!peer_->membership_req_pending());
211  assert(!peer_->close_manager_->IsMembershipInUse());
213  }
214 
215 private:
217 };
218 
219 //
220 // Constructor for BgpPeerFamilyAttributes.
221 //
223  const BgpNeighborConfig *config,
224  const BgpFamilyAttributesConfig &family_config) {
225  if (family_config.loop_count) {
226  loop_count = family_config.loop_count;
227  } else {
228  loop_count = config->loop_count();
229  }
230  prefix_limit = family_config.prefix_limit;
231  idle_timeout = family_config.idle_timeout;
233 
234  if (config->router_type() == "bgpaas-client") {
235  if (family_config.family == "inet") {
237  } else if (family_config.family == "inet6") {
239  }
240  }
241 }
242 
244  RibExportPolicy policy;
245  BgpPeerFamilyAttributes *family_attributes =
246  family_attributes_list_[family];
247  if (!family_attributes) {
249  as_override_, peer_close_->IsCloseLongLivedGraceful(),
251  } else {
253  as_override_, peer_close_->IsCloseLongLivedGraceful(),
254  as4_supported_, family_attributes->gateway_address,
255  -1, cluster_id_, family_attributes->default_tunnel_encap_list,
256  local_as_);
257  }
258 
259  if (private_as_action_ == "remove") {
260  policy.SetRemovePrivatePolicy(false, false, true);
261  } else if (private_as_action_ == "remove-all") {
262  policy.SetRemovePrivatePolicy(true, false, true);
263  } else if (private_as_action_ == "replace-all") {
264  policy.SetRemovePrivatePolicy(true, true, true);
265  }
266 
267  return policy;
268 }
269 
270 void BgpPeer::ReceiveEndOfRIB(Address::Family family, size_t msgsize) {
271  close_manager_->ProcessEORMarkerReceived(family);
272  eor_receive_timer_[family]->Cancel();
273 
274  // If EoR for RTarget is received, start registration for other families.
275  if (family == Address::RTARGET)
277 }
278 
280  tbb::spin_mutex::scoped_lock lock(spin_mutex_);
281 
282  // Bail if there's no session for the peer anymore.
283  if (!session_)
284  return;
285 
286  BgpProto::Update update;
287  uint16_t afi;
288  uint8_t safi;
289  tie(afi, safi) = BgpAf::FamilyToAfiSafi(family);
290  BgpMpNlri *nlri = new BgpMpNlri(BgpAttribute::MPUnreachNlri, afi, safi);
291  update.path_attributes.push_back(nlri);
292  uint8_t data[256];
293  int msgsize = BgpProto::Encode(&update, data, sizeof(data), NULL,
295  assert(msgsize > BgpProto::kMinMessageSize);
296  session_->Send(data, msgsize, NULL);
298  inc_tx_update();
299  BGP_LOG_PEER(Message, this, SandeshLevel::SYS_INFO,
301  "EndOfRib marker family " << Address::FamilyToString(family) <<
302  " size " << msgsize);
303 }
304 
306  BgpTable *table = GetRoutingInstance()->GetTable(family);
307  return server_->membership_mgr()->GetRibOutQueueDepth(this, table);
308 }
309 
312 }
313 
315  return family == Address::RTARGET ?
317 }
318 
320  return server_->IsServerStartingUp();
321 }
322 
324  return peer_close_->IsCloseGraceful();
325 }
326 
329 }
330 
332  if (!IsReady())
333  return false;
334 
335  // Send EoR if wait time has exceeded the configured maximum.
337  SendEndOfRIBActual(family);
338  return false;
339  }
340 
341  // Defer if output queue has not been fully drained yet.
342  uint32_t output_depth = GetOutputQueueDepth(family);
343  if (output_depth) {
345  BGP_LOG_PEER(Message, this, SandeshLevel::SYS_INFO,
347  "EndOfRib Send Timer rescheduled for family " <<
348  Address::FamilyToString(family) << " to fire after " <<
349  kEndOfRibSendRetryTime << " second(s) " <<
350  "due to non-empty output queue (" << output_depth << ")");
351  return true;
352  }
353 
354  // Send EoR if we are not still under [re-]starting phase.
355  if (!IsServerStartingUp()) {
356  SendEndOfRIBActual(family);
357  return false;
358  }
359 
360  // Defer if configuration processing is not complete yet.
363  BGP_LOG_PEER(Message, this, SandeshLevel::SYS_INFO,
365  "EndOfRib Send Timer rescheduled for family " <<
366  Address::FamilyToString(family) << " to fire after " <<
367  kEndOfRibSendRetryTime << " second(s) " <<
368  "as bgp (under restart) has not completed initial configuration"
369  " processing");
370  return true;
371  }
372 
373  // For all families except route-target, wait for a certain amount of time
374  // before sending eor as bgp is still in [re-]starting phase (60s).
375  if (family != Address::RTARGET) {
377  BGP_LOG_PEER(Message, this, SandeshLevel::SYS_INFO,
379  "EndOfRib Send Timer rescheduled for family " <<
380  Address::FamilyToString(family) << " to fire after " <<
381  kEndOfRibSendRetryTime << " second(s) " <<
382  "as bgp is still under [re-]starting phase");
383  return true;
384  }
385 
386  // Defer EoR if any new route-target was added to the table recently (6s).
388  0.02 * server_->GetEndOfRibSendTime()) {
390  BGP_LOG_PEER(Message, this, SandeshLevel::SYS_INFO,
392  "EndOfRib Send Timer rescheduled for family " <<
393  Address::FamilyToString(family) << " to fire after " <<
394  kEndOfRibSendRetryTime << " second(s) " <<
395  "as new route-targets are still being added to the table");
396  return true;
397  }
398 
399  // Send eor as [re-]starting phase is complete for this family.
400  SendEndOfRIBActual(family);
401  return false;
402 }
403 
406  BGP_LOG_PEER(Message, this, SandeshLevel::SYS_INFO,
408  "EndOfRib Send Timer scheduled for family " <<
409  Address::FamilyToString(family) <<
410  " to fire after " << kEndOfRibSendRetryTime << " second(s)");
412  boost::bind(&BgpPeer::EndOfRibSendTimerExpired, this, family),
413  boost::bind(&BgpPeer::EndOfRibTimerErrorHandler, this, _1, _2));
414 }
415 
416 void BgpPeer::BGPPeerInfoSend(const BgpPeerInfoData &peer_info) const {
417  assert(!peer_info.get_name().empty());
418  BGP_UVE_SEND(BGPPeerInfo, peer_info);
419 }
420 
422  return !membership_req_pending_;
423 }
424 
425 //
426 // Callback from BgpMembershipManager.
427 // Update pending membership request count and send EndOfRib for the family
428 // in question.
429 //
431  if (close_manager_->IsMembershipInUse()) {
432  close_manager_->MembershipRequestCallback();
433  return;
434  }
435 
436  assert(membership_req_pending_ > 0);
438 
439  // Resume if CloseManager is waiting to use membership manager.
441  close_manager_->IsMembershipInWait()) {
442  close_manager_->MembershipRequest();
443  }
444 
445  // Resume close if it was deferred and this is the last pending callback.
446  // Don't bother sending EndOfRib if close is deferred.
447  if (defer_close_) {
449  defer_close_ = false;
450  trigger_.Set();
451  }
452  return;
453  }
454 
455  SendEndOfRIB(table->family());
456 }
457 
459  BgpPath *path) {
460  return close_manager_->MembershipPathCallback(tpart, route, path);
461 }
462 
465  graceful_close_ = true;
466  return true;
467 }
468 
470  const BgpNeighborConfig *config)
471  : server_(server),
472  rtinstance_(instance),
473  peer_key_(config),
474  peer_port_(config->source_port()),
475  peer_name_(config->name()),
476  router_type_(config->router_type()),
477  config_(config),
478  index_(server->RegisterPeer(this)),
479  trigger_(boost::bind(&BgpPeer::ResumeClose, this),
480  TaskScheduler::GetInstance()->GetTaskId("bgp::StateMachine"),
481  GetTaskInstance()),
482  prefix_limit_idle_timer_(
483  TimerManager::CreateTimer(*server->ioservice(),
484  "BGP prefix limit idle timer",
485  TaskScheduler::GetInstance()->GetTaskId("bgp::StateMachine"),
486  GetTaskInstance())),
487  prefix_limit_trigger_(boost::bind(&BgpPeer::CheckPrefixLimits, this),
488  TaskScheduler::GetInstance()->GetTaskId("bgp::StateMachine"),
489  GetTaskInstance()),
490  buffer_capacity_(GetBufferCapacity()),
491  session_(NULL),
492  keepalive_timer_(TimerManager::CreateTimer(*server->ioservice(),
493  "BGP keepalive timer",
494  TaskScheduler::GetInstance()->GetTaskId("bgp::StateMachine"),
495  GetTaskInstance())),
496  eor_send_timer_start_time_(0),
497  send_ready_(true),
498  admin_down_(config->admin_down()),
499  passive_(config->passive()),
500  resolve_paths_(config->router_type() == "bgpaas-client"),
501  as_override_(config->as_override()),
502  cluster_id_(config->cluster_id()),
503  origin_override_(config->origin_override()),
504  defer_close_(false),
505  graceful_close_(true),
506  as4_supported_(false),
507  vpn_tables_registered_(false),
508  hold_time_(config->hold_time()),
509  local_as_(config->local_as()),
510  peer_as_(config->peer_as()),
511  local_bgp_id_(config->local_identifier()),
512  peer_bgp_id_(0),
513  peer_type_((config->peer_as() == config->local_as()) ?
514  BgpProto::IBGP : BgpProto::EBGP),
515  state_machine_(BgpStaticObjectFactory::Create<StateMachine>(this)),
516  peer_close_(BgpStaticObjectFactory::Create<BgpPeerClose>(this)),
517  peer_stats_(new PeerStats(this)),
518  deleter_(new DeleteActor(this)),
519  instance_delete_ref_(this, instance ? instance->deleter() : NULL),
520  flap_count_(0),
521  total_flap_count_(0),
522  last_flap_(0),
523  dscp_listener_id_(-1),
524  inuse_authkey_type_(AuthenticationData::NIL),
525  asn_listener_id_(-1),
526  instance_op_(-1) {
527  buffer_.reserve(buffer_capacity_);
528  close_manager_.reset(
529  BgpStaticObjectFactory::Create<PeerCloseManager>(static_cast<IPeerClose*>(peer_close_.get())));
530  ostringstream oss1;
531  oss1 << peer_key_.endpoint.address();
533  oss1 << ":" << dec << peer_key_.endpoint.port();
534  to_str_ = oss1.str();
535 
536  ostringstream oss2;
537  if (rtinstance_)
538  oss2 << rtinstance_->name() << ":";
539  oss2 << server_->localname() << ":";
540  oss2 << peer_name();
541  uve_key_str_ = oss2.str();
542 
543  if (router_type_ == "control-node" ||
544  router_type_ == "external-control-node") {
545  peer_is_control_node_ = true;
546  } else {
547  peer_is_control_node_ = false;
548  }
549 
551  &BgpPeer::DSCPUpdateCallback, this, _1));
552  if (IsRouterTypeBGPaaS()) {
554  &BgpPeer::ASNUpdateCallback, this, _1, _2));
556  boost::bind(&BgpPeer::RoutingInstanceCallback, this, _1, _2));
557  }
558 
560  BGP_LOG_PEER(Event, this, SandeshLevel::SYS_INFO, BGP_LOG_FLAG_ALL,
561  BGP_PEER_DIR_NA, "Created");
562 
563  if (rtinstance_ && peer_name_.find(rtinstance_->name()) == 0) {
564  peer_basename_ = peer_name_.substr(rtinstance_->name().size() + 1);
565  } else {
567  }
568 
569  for (Address::Family family = Address::UNSPEC;
570  family < Address::NUM_FAMILIES;
571  family = static_cast<Address::Family>(family + 1)) {
572  family_primary_path_count_[family] = 0;
573  eor_send_timer_[family] =
575  "BGP EoR Send timer for " + Address::FamilyToString(family),
576  TaskScheduler::GetInstance()->GetTaskId("bgp::StateMachine"),
577  GetTaskInstance());
578  eor_receive_timer_[family] =
580  "BGP EoR Receive timer for " + Address::FamilyToString(family),
581  TaskScheduler::GetInstance()->GetTaskId("bgp::StateMachine"),
582  GetTaskInstance());
583  }
584 
585  total_path_count_ = 0;
587 
588  // Check rtinstance_ to accommodate unit tests.
589  if (resolve_paths_ && rtinstance_) {
592  }
593 
597 
598  BgpPeerInfoData peer_info;
599  peer_info.set_name(ToUVEKey());
600  peer_info.set_admin_down(admin_down_);
601  peer_info.set_passive(passive_);
602  peer_info.set_as_override(as_override_);
603  peer_info.set_origin_override(origin_override_.origin_override);
605  peer_info.set_route_origin(
607  } else {
608  peer_info.set_route_origin("-");
609  }
610  peer_info.set_router_type(router_type_);
611  peer_info.set_cluster_id(Ip4Address(cluster_id_).to_string());
612  peer_info.set_peer_type(
613  PeerType() == BgpProto::IBGP ? "internal" : "external");
614  peer_info.set_local_asn(local_as_);
615  peer_info.set_peer_asn(peer_as_);
616  peer_info.set_peer_port(peer_port_);
617  peer_info.set_hold_time(hold_time_);
618  peer_info.set_local_id(local_bgp_id_);
619  peer_info.set_configured_families(configured_families_);
620  peer_info.set_peer_address(peer_key_.endpoint.address().to_string());
621  BGPPeerInfoSend(peer_info);
622 }
623 
625  assert(!close_manager()->IsCloseInProgress());
626  assert(!IsCloseInProgress());
627  assert(GetTotalPathCount() == 0);
630  BgpPeerInfoData peer_info;
631  peer_info.set_name(ToUVEKey());
632  peer_info.set_deleted(true);
633  BGPPeerInfoSend(peer_info);
634 
635  PeerStatsData peer_stats_data;
636  peer_stats_data.set_name(ToUVEKey());
637  peer_stats_data.set_deleted(true);
638  assert(!peer_stats_data.get_name().empty());
639  BGP_UVE_SEND2(PeerStatsUve, peer_stats_data, "ObjectBgpPeer");
640 
641  PeerFlapData peer_flap_data;
642  peer_flap_data.set_name(ToUVEKey());
643  peer_flap_data.set_deleted(true);
644  assert(!peer_flap_data.get_name().empty());
645  BGP_UVE_SEND2(PeerFlap, peer_flap_data, "ObjectBgpPeer");
646 
647  BGP_LOG_PEER(Event, this, SandeshLevel::SYS_INFO, BGP_LOG_FLAG_ALL,
648  BGP_PEER_DIR_NA, "Deleted");
649 }
650 
652  if (!admin_down_)
653  state_machine_->Initialize();
654 }
655 
657  // For testing only - configure through environment variable.
658  char *buffer_capacity_str = getenv("BGP_PEER_BUFFER_SIZE");
659  if (buffer_capacity_str) {
660  size_t env_buffer_capacity = strtoul(buffer_capacity_str, NULL, 0);
661  if (env_buffer_capacity < kMinBufferCapacity)
662  env_buffer_capacity = kMinBufferCapacity;
663  if (env_buffer_capacity > kMaxBufferCapacity)
664  env_buffer_capacity = kMaxBufferCapacity;
665  return env_buffer_capacity;
666  }
667 
668  // Return internal default based on peer router-type.
669  if (IsRouterTypeBGPaaS()) {
670  return kMinBufferCapacity;
671  } else {
672  return kMaxBufferCapacity;
673  }
674 }
675 
676 bool BgpPeer::CheckSplitHorizon(uint32_t server_cluster_id,
677  uint32_t ribout_cid) const {
678  if (PeerType() == BgpProto::IBGP) {
679  // check if router is a route reflector
680  if (!server_cluster_id) return true;
681  // check if received from client or non-client by comparing the clusterId
682  // of router with that of peer from which we this route is received
683  if (server_cluster_id != cluster_id_) {
684  // If received from non-client, reflect to all the clients only
685  if (ribout_cid && ribout_cid != server_cluster_id) {
686  return true;
687  }
688  }
689  }
690  return false;
691 }
692 
695  if (!instance_mgr)
696  return NULL;
697  RoutingInstance *master = instance_mgr->GetDefaultRoutingInstance();
698  if (!master)
699  return NULL;
700  return master->GetTable(Address::RTARGET);
701 }
702 
704  BgpAttrSpec attrs;
706  attrs.push_back(&nexthop);
708  attrs.push_back(&origin);
709  return server_->attr_db()->Locate(attrs);
710 }
711 
712 // Add one route-target route to bgp.rtarget.0 table.
714  RouteTargetList::const_iterator it) {
715  const RouteTarget rtarget = *it;
716  DBRequest req;
717  RTargetPrefix rt_prefix(as, rtarget);
718  req.key.reset(new RTargetTable::RequestKey(rt_prefix, this));
719  req.data.reset(new RTargetTable::RequestData(attr, 0, 0, 0, 0));
721  table->Enqueue(&req);
722 }
723 
724 // Add import route-targets of associated routing-instance in order to attract
725 // the VN routes, if bgpaas session comes up within the instance.
727  if (!IsRouterTypeBGPaaS())
728  return;
729  assert(IsReady());
730  BgpTable *table = GetRTargetTable();
731  assert(table);
734  for (RouteTargetList::const_iterator it = rtargets_.begin();
735  it != rtargets_.end(); it++) {
736  BGPaaSAddRTarget(as, table, attr, it);
737  }
738 }
739 
740 // Delete one route-target route from bgp.rtarget.0 table.
742  RouteTargetList::const_iterator it) {
743  const RouteTarget rtarget = *it;
744  DBRequest req;
745  RTargetPrefix rt_prefix(as, rtarget);
746  req.key.reset(new RTargetTable::RequestKey(rt_prefix, this));
748  table->Enqueue(&req);
749 }
750 
751 // Delete import route-targets of associated routing-instance in order to
752 // not to attract the VN routes any more, if bgpaas session goes down within
753 // the instance.
755  if (!IsRouterTypeBGPaaS())
756  return;
757  BgpTable *table = GetRTargetTable();
758  if (!table)
759  return;
760  for (RouteTargetList::const_iterator it = rtargets_.begin();
761  it != rtargets_.end(); it++) {
762  BGPaaSDeleteRTarget(as, table, it);
763  }
764  rtargets_.clear();
765 }
766 
767 void BgpPeer::ASNUpdateCallback(as_t old_asn, as_t old_local_asn) {
768  CHECK_CONCURRENCY("bgp::Config");
769  DeleteRTargets(old_local_asn);
770  if (!IsReady())
771  return;
773 }
774 
775 // Process changes to routing-instance configuration. Specifically, we need
776 // to track all import route-targets so that they can be correctly updated
777 // when bgpaas sessions come up or go down.
778 void BgpPeer::RoutingInstanceCallback(const std::string &vrf_name, int op) {
779  assert(IsRouterTypeBGPaaS());
781  return;
782  if (vrf_name != rtinstance_->name())
783  return;
785  RoutingInstance *master = instance_mgr->GetDefaultRoutingInstance();
786  BgpTable *table = master->GetTable(Address::RTARGET);
787  assert(table);
790  boost::bind(&BgpPeer::BGPaaSAddRTarget, this,
791  server_->local_autonomous_system(), table, attr, _1),
792  boost::bind(&BgpPeer::BGPaaSDeleteRTarget, this,
793  server_->local_autonomous_system(), table, _1));
795 }
796 
797 void BgpPeer::NotifyEstablished(bool established) {
798  if (established) {
799  if (IsRouterTypeBGPaaS()) {
802  } else {
804  }
805  } else {
806  if (IsRouterTypeBGPaaS()) {
808  } else {
810  }
811  }
812 }
813 
815 }
816 
817 // Just return the first entry for now.
819  KeyType *key_type) const {
820  if (auth_data_.Empty()) {
821  return false;
822  }
823  assert(auth_key);
825  *auth_key = *iter;
826  *key_type = auth_data_.key_type();
827  return true;
828 }
829 
831  const AuthenticationData &input_auth_data = config->auth_data();
832 
833  if (auth_data_ == input_auth_data) {
834  return false;
835  }
836 
837  auth_data_ = input_auth_data;
838  return InstallAuthKeys();
839 }
840 
842  if (!PeerAddress()) {
843  return false;
844  }
845 
846  AuthenticationKey auth_key;
847  KeyType key_type;
848  bool valid = GetBestAuthKey(&auth_key, &key_type);
849  if (valid) {
850  if (key_type == AuthenticationData::MD5) {
851  LogInstallAuthKeys("Listen", "add", auth_key, key_type);
852  SetListenSocketAuthKey(auth_key, key_type);
853  SetInuseAuthKeyInfo(auth_key, key_type);
854  }
855  } else {
856  // If there are no valid available keys but an older one is currently
857  // installed, un-install it.
859  LogInstallAuthKeys("Listen", "delete", inuse_auth_key_,
862  // Resetting the key information must be done last.
864  }
865  }
866  return true;
867 }
868 
870  inuse_auth_key_ = key;
872 }
873 
877 }
878 
880  KeyType key_type) {
881  if (key_type == AuthenticationData::MD5) {
883  SetListenSocketMd5Option(PeerAddress(), auth_key.value);
884  }
885 }
886 
890  }
891 }
892 
895  assert(!inuse_auth_key_.value.empty());
896  LogInstallAuthKeys("Session", "add", inuse_auth_key_,
899  }
900 }
901 
903  uint8_t dscp_value = server_->global_qos()->control_dscp();
904 
905  if (!session->socket()) {
906  return;
907  }
908  if (dscp_value != 0xFF) {
910  }
911 }
912 
914  return inuse_auth_key_.value;
915 }
916 
917 void BgpPeer::LogInstallAuthKeys(const string &socket_name,
918  const string &oper, const AuthenticationKey &auth_key,
919  KeyType key_type) {
920  string logstr = socket_name + " socket kernel " + oper + " of key id "
921  + integerToString(auth_key.id) + ", type "
923  + ", peer " + peer_name_;
924  BGP_LOG_PEER(Config, this, SandeshLevel::SYS_INFO, BGP_LOG_FLAG_ALL,
925  BGP_PEER_DIR_NA, logstr);
926 }
927 
928 //
929 // Check if the configured prefix limit for any address family has been
930 // exceeded. If yes, clear the peer by sending a notification with a cease
931 // subcode of MaxPrefixes.
932 //
934  RetryDelete();
935  if (!IsReady())
936  return true;
937  for (size_t idx = Address::UNSPEC; idx < Address::NUM_FAMILIES; ++idx) {
938  BgpPeerFamilyAttributes *family_attributes =
940  if (!family_attributes || family_attributes->prefix_limit == 0)
941  continue;
942  if (family_primary_path_count_[idx] <= family_attributes->prefix_limit)
943  continue;
945  StartPrefixLimitIdleTimer(family_attributes->idle_timeout * 1000);
946  break;
947  }
948  return true;
949 }
950 
951 //
952 // Process family attributes configuration and update the family attributes
953 // list.
954 //
955 // Return true is there's a change, false otherwise.
956 //
958  FamilyAttributesList family_attributes_list(Address::NUM_FAMILIES);
959  BOOST_FOREACH(const BgpFamilyAttributesConfig family_config,
961  Address::Family family =
962  Address::FamilyFromString(family_config.family);
963  assert(family != Address::UNSPEC);
964  BgpPeerFamilyAttributes *family_attributes =
965  new BgpPeerFamilyAttributes(config, family_config);
966  family_attributes_list[family] = family_attributes;
967  }
968 
969  int ret = STLSortedCompare(
970  family_attributes_list.begin(), family_attributes_list.end(),
974  family_attributes_list_ = family_attributes_list;
976  return (ret != 0);
977 }
978 
980  if (config->router_type() == "bgpaas-client") {
982  } else {
984  }
985 }
986 
989 }
990 
992  if (IsDeleted())
993  return;
994 
995  config_ = config;
996 
997  // During peer deletion, configuration gets completely deleted. In that
998  // case, there is no need to update the rest and flap the peer.
999  if (!config_)
1000  return;
1001 
1002  bool clear_session = false;
1003  bool admin_down_changed = false;
1004  BgpPeerInfoData peer_info;
1005  peer_info.set_name(ToUVEKey());
1006 
1007  if (admin_down_ != config->admin_down()) {
1009  peer_info.set_admin_down(admin_down_);
1010  admin_down_changed = true;
1011  }
1012 
1013  if (passive_ != config->passive()) {
1014  passive_ = config->passive();
1015  peer_info.set_passive(passive_);
1016  clear_session = true;
1017  }
1018 
1019  if (as_override_ != config->as_override()) {
1021  peer_info.set_as_override(as_override_);
1022  clear_session = true;
1023  }
1024 
1025  if (cluster_id_ != config->cluster_id()) {
1027  peer_info.set_cluster_id(Ip4Address(cluster_id_).to_string());
1028  clear_session = true;
1029  }
1030 
1031  OriginOverride origin_override(config->origin_override());
1032  if (origin_override_ != origin_override) {
1033  origin_override_ = origin_override;
1034  peer_info.set_origin_override(origin_override_.origin_override);
1036  peer_info.set_route_origin(config->origin_override().origin);
1037  } else {
1038  peer_info.set_route_origin("-");
1039  }
1040  clear_session = true;
1041  }
1042 
1043  if (router_type_ != config->router_type()) {
1045  peer_info.set_router_type(router_type_);
1046  resolve_paths_ = (config->router_type() == "bgpaas-client");
1047  clear_session = true;
1048  }
1049  if (router_type_ == "control-node" ||
1050  router_type_ == "external-control-node") {
1051  peer_is_control_node_ = true;
1052  } else {
1053  peer_is_control_node_ = false;
1054  }
1055 
1056  // Check if there is any change in the peer address.
1057  // If the peer address is changing, remove the key for the older address.
1058  // Update with the new peer address and then process the key chain info
1059  // for the new peer below.
1060  BgpPeerKey key(config);
1061  if (peer_key_ != key) {
1063  peer_key_ = key;
1064  peer_info.set_peer_address(peer_key_.endpoint.address().to_string());
1065  clear_session = true;
1066  }
1068  clear_session = true;
1069  }
1070 
1071  if (peer_port_ != config->source_port()) {
1073  peer_info.set_peer_port(peer_port_);
1074  clear_session = true;
1075  }
1077 
1078  if (local_as_ != config->local_as()) {
1079  BGP_LOG_STR(BgpConfig, SandeshLevel::SYS_DEBUG,
1081  "Updated Local Autonomous System from " <<
1082  local_as_ << " to " <<
1083  config->local_as());
1084 
1085  local_as_ = config->local_as();
1086  peer_info.set_local_asn(local_as_);
1087  clear_session = true;
1088  }
1089 
1090  if (hold_time_ != config->hold_time()) {
1091  BGP_LOG_STR(BgpConfig, SandeshLevel::SYS_DEBUG,
1093  "Updated Hold Time from " <<
1094  hold_time_ << " to " <<
1095  config->hold_time());
1096 
1098  peer_info.set_hold_time(hold_time_);
1099  clear_session = true;
1100  }
1101 
1102  if (peer_as_ != config->peer_as()) {
1103  BGP_LOG_STR(BgpConfig, SandeshLevel::SYS_DEBUG,
1105  "Updated Peer Autonomous System from " <<
1106  peer_as_ << " to " <<
1107  config->peer_as());
1108 
1109  peer_as_ = config->peer_as();
1110  peer_info.set_peer_asn(peer_as_);
1111  clear_session = true;
1112  }
1113 
1114  boost::system::error_code ec;
1115  uint32_t local_bgp_id = config->local_identifier();
1116  if (local_bgp_id_ != local_bgp_id) {
1117  local_bgp_id_ = local_bgp_id;
1118  peer_info.set_local_id(local_bgp_id_);
1119  clear_session = true;
1120  }
1121 
1122  BgpProto::BgpPeerType old_type = PeerType();
1124  if (old_type != PeerType()) {
1125  peer_info.set_peer_type(
1126  PeerType() == BgpProto::IBGP ? "internal" : "external");
1127  clear_session = true;
1128  }
1129 
1130  // Check if there is any change in private-as-action configuration.
1133  clear_session = true;
1134  }
1135 
1136  // Check if there is any change in the configured address families.
1138  peer_info.set_configured_families(configured_families_);
1139  clear_session = true;
1140  } else {
1142  }
1143 
1144  // Note that the state machine would have been stopped via SetAdminDown
1145  // if admin down was set to true above. Further, it's not necessary to
1146  // clear the peer if it's already admin down.
1147  if (!admin_down_changed && !admin_down_ && clear_session) {
1148  BGP_LOG_PEER(Config, this, SandeshLevel::SYS_INFO, BGP_LOG_FLAG_ALL,
1150  "Session cleared due to configuration change");
1152  }
1153 
1154  // Send the UVE as appropriate.
1155  if (admin_down_changed || clear_session) {
1157  BGPPeerInfoSend(peer_info);
1158  }
1159 }
1160 
1162  CHECK_CONCURRENCY("bgp::Config");
1163  config_ = NULL;
1164 }
1165 
1167  return deleter_.get();
1168 }
1169 
1170 //
1171 // Check if the given address family has been negotiated with the peer.
1172 //
1174  // Bail if the family is not configured locally.
1175  if (!LookupFamily(family))
1176  return false;
1177 
1178  // Check if the peer advertised it in his Open message.
1179  uint16_t afi;
1180  uint8_t safi;
1181  tie(afi, safi) = BgpAf::FamilyToAfiSafi(family);
1182  return MpNlriAllowed(afi, safi);
1183 }
1184 
1185 // Release resources for a peer that is going to be deleted.
1187  if (index_ != -1) {
1188  server_->UnregisterPeer(this);
1189  index_ = -1;
1190  }
1193 
1194  for (Address::Family family = Address::UNSPEC;
1195  family < Address::NUM_FAMILIES;
1196  family = static_cast<Address::Family>(family + 1)) {
1199  }
1200 }
1201 
1202 // IsReady
1203 //
1204 // Check whether this peer is up and ready
1205 //
1206 bool BgpPeer::IsReady() const {
1207  return state_machine_->get_state() == StateMachine::ESTABLISHED;
1208 }
1209 
1210 bool BgpPeer::IsXmppPeer() const {
1211  return false;
1212 }
1213 
1215  return ntohl(local_bgp_id_);
1216 }
1217 
1219  return Ip4Address(ntohl(local_bgp_id_)).to_string();
1220 }
1221 
1222 uint32_t BgpPeer::bgp_identifier() const {
1223  return ntohl(peer_bgp_id_);
1224 }
1225 
1227  return Ip4Address(ntohl(peer_bgp_id_)).to_string();
1228 }
1229 
1232  ostringstream oss;
1233  if (session_)
1235  oss << endpoint;
1236  return oss.str();
1237 }
1238 
1240  if (!family_attributes_list_[family])
1241  return string();
1242  return family_attributes_list_[family]->gateway_address.to_string();
1243 }
1244 
1245 //
1246 // Customized close routing for BgpPeers.
1247 //
1248 // Reset all stored capabilities information and cancel outstanding timers.
1249 //
1253 
1254  for (Address::Family family = Address::UNSPEC;
1255  family < Address::NUM_FAMILIES;
1256  family = static_cast<Address::Family>(family + 1)) {
1257  eor_send_timer_[family]->Cancel();
1258  eor_receive_timer_[family]->Cancel();
1259  }
1260 
1261  if (close_manager_->IsInDeleteState())
1263 }
1264 
1265 //
1266 // Close this peer by closing all of it's RIBs.
1267 //
1268 void BgpPeer::Close(bool graceful) {
1269  send_ready_ = true;
1270  if (membership_req_pending_ && !close_manager_->IsMembershipInUse()) {
1271  BGP_LOG_PEER(Event, this, SandeshLevel::SYS_INFO, BGP_LOG_FLAG_ALL,
1272  BGP_PEER_DIR_NA, "Close procedure deferred");
1273  defer_close_ = true;
1274 
1275  // Note down non-graceful closures. Once a close is non-graceful,
1276  // it shall remain as non-graceful.
1277  graceful_close_ &= graceful;
1278  return;
1279  }
1280 
1281  peer_close_->Close(graceful);
1282 }
1283 
1285  return peer_close_.get();
1286 }
1287 
1289  return peer_close_.get();
1290 }
1291 
1293  const BgpPath *old_path, uint32_t path_flags) const {
1294  peer_close()->UpdateRouteStats(family, old_path, path_flags);
1295 }
1296 
1298  return peer_stats_.get();
1299 }
1300 
1302  return peer_stats_.get();
1303 }
1304 
1305 void BgpPeer::Clear(int subcode) {
1306  CHECK_CONCURRENCY("bgp::Config", "bgp::StateMachine");
1307  state_machine_->Shutdown(subcode);
1308 }
1309 
1310 //
1311 // Check whether this peer has been marked for deletion from configuration
1312 //
1313 bool BgpPeer::IsDeleted() const {
1314  return deleter_->IsDeleted();
1315 }
1316 
1318  return close_manager_->IsInGRTimerWaitState();
1319 }
1320 
1322  CHECK_CONCURRENCY("bgp::Config", "bgp::StateMachine");
1323 
1324  // trigger is set only after defer_close is reset
1325  assert(!(defer_close_ && trigger_.IsSet()));
1326  return defer_close_ || trigger_.IsSet() ||
1327  (close_manager_->IsCloseInProgress() &&
1329 }
1330 
1332  return state_machine_->get_state();
1333 }
1334 
1335 const string BgpPeer::GetStateName() const {
1336  return state_machine_->StateName();
1337 }
1338 
1341  return NULL;
1342 
1344  if (session == NULL)
1345  return NULL;
1346 
1347  // Set valid keys, if any, in the socket.
1349 
1350  BgpSession *bgp_session = static_cast<BgpSession *>(session);
1351  BindLocalEndpoint(bgp_session);
1352  bgp_session->set_peer(this);
1353  return bgp_session;
1354 }
1355 
1356 void BgpPeer::SetAdminState(bool down, int subcode) {
1357  CHECK_CONCURRENCY("bgp::Config");
1358  if (admin_down_ == down)
1359  return;
1360  admin_down_ = down;
1361  state_machine_->SetAdminState(down, subcode);
1362  if (admin_down_) {
1363  BGP_LOG_PEER(Config, this, SandeshLevel::SYS_INFO, BGP_LOG_FLAG_ALL,
1364  BGP_PEER_DIR_NA, "Session cleared due to admin down");
1365  }
1366 }
1367 
1369  session->set_peer(this);
1370 
1371  // Set valid keys, if any, in the socket.
1373 
1374  // Set control dscp, if any
1376 
1377  return state_machine_->PassiveOpen(session);
1378 }
1379 
1380 void BgpPeer::Register(BgpTable *table, const RibExportPolicy &policy) {
1381  // In a highly corner case scenario, GR timer could fire right after a
1382  // session comes back up. In that case, CloseManager possibly could still
1383  // be using membership manager. Instead of creating a queue of these
1384  // register requests until close manager is done processing and process
1385  // them later, we could just as well just reset the session.
1386  if (close_manager_->IsMembershipInUse()) {
1387  BGP_LOG_PEER(Config, this, SandeshLevel::SYS_NOTICE, BGP_LOG_FLAG_ALL,
1388  BGP_PEER_DIR_IN, "Session cleared due to GR not ready");
1389  Close(true);
1390  }
1391 
1392  if (close_manager_->IsMembershipInWait())
1393  assert(membership_req_pending_ > 0);
1394  BgpMembershipManager *membership_mgr = server_->membership_mgr();
1396  membership_mgr->Register(this, table, policy);
1397 
1398  // Start EndOfRib receive timer.
1400 }
1401 
1403  if (close_manager_->IsMembershipInUse()) {
1404  BGP_LOG_PEER(Config, this, SandeshLevel::SYS_NOTICE, BGP_LOG_FLAG_ALL,
1405  BGP_PEER_DIR_IN, "Session cleared due to GR not ready");
1406  Close(true);
1407  }
1408 
1409  if (close_manager_->IsMembershipInWait())
1410  assert(membership_req_pending_ > 0);
1411  BgpMembershipManager *membership_mgr = server_->membership_mgr();
1412  membership_mgr->RegisterRibIn(this, table);
1413 
1414  // Start EndOfRib receive timer.
1416 }
1417 
1418 //
1419 // Register to tables for negotiated address families.
1420 //
1421 // If the route-target family is negotiated, defer ribout registration
1422 // to VPN tables till we receive End-Of-RIB marker for the route-target
1423 // NLRI or till the EndOfRibTimer expires. This ensures that we do not
1424 // start sending VPN routes to the peer till we know what route targets
1425 // the peer is interested in.
1426 //
1427 // Note that we do ribin registration right away even if the route-target
1428 // family is negotiated. This allows received VPN routes to be processed
1429 // normally before ribout registration to VPN tables is completed.
1430 //
1432  RoutingInstance *instance = GetRoutingInstance();
1433 
1434  BGP_LOG_PEER(Event, this, SandeshLevel::SYS_INFO, BGP_LOG_FLAG_ALL,
1435  BGP_PEER_DIR_NA, "Established");
1436 
1437  vector<Address::Family> family_list = list_of
1439  BOOST_FOREACH(Address::Family family, family_list) {
1440  if (!IsFamilyNegotiated(family))
1441  continue;
1442  BgpTable *table = instance->GetTable(family);
1443  BGP_LOG_PEER_TABLE(this, SandeshLevel::SYS_DEBUG, BGP_LOG_FLAG_TRACE,
1444  table, "Register peer with the table");
1445  Register(table, BuildRibExportPolicy(family));
1446  }
1447 
1448 
1449  if (((router_type_ == "bgpaas-client") ||
1450  (router_type_ == "bgpaas-server")) &&
1451  (instance->routing_instance_vxlan() != "")) {
1453  if (mgr != nullptr) {
1454  RoutingInstance *vxlan_ri =
1455  mgr->GetRoutingInstance(instance->routing_instance_vxlan());
1456  if (vxlan_ri != nullptr) {
1457  BgpTable *table = vxlan_ri->GetTable(Address::EVPN);
1458  BGP_LOG_PEER_TABLE(this, SandeshLevel::SYS_INFO, BGP_LOG_FLAG_TRACE,
1459  table, "Register ribin for peer with the table");
1460  Register(table);
1461  }
1462  }
1463  }
1464 
1465  vpn_tables_registered_ = false;
1468  return;
1469  }
1470 
1472  BgpTable *table = instance->GetTable(family);
1473  BGP_LOG_PEER_TABLE(this, SandeshLevel::SYS_DEBUG, BGP_LOG_FLAG_TRACE,
1474  table, "Register peer with the table");
1475  Register(table, BuildRibExportPolicy(family));
1476 
1477  vector<Address::Family> vpn_family_list = list_of
1479  (Address::MVPN);
1480  BOOST_FOREACH(Address::Family vpn_family, vpn_family_list) {
1481  if (!IsFamilyNegotiated(vpn_family))
1482  continue;
1483  BgpTable *table = instance->GetTable(vpn_family);
1484  BGP_LOG_PEER_TABLE(this, SandeshLevel::SYS_INFO, BGP_LOG_FLAG_TRACE,
1485  table, "Register ribin for peer with the table");
1486  Register(table);
1487  }
1488 }
1489 
1490 const vector<Address::Family> BgpPeer::supported_families_ = list_of
1491  (Address::INET)
1494  (Address::EVPN)
1496  (Address::ERMVPN)
1497  (Address::MVPN)
1498  (Address::INET6)
1500 
1502  BgpProto::OpenMessage openmsg;
1503  openmsg.as_num = local_as_ > 0xffff ? AS_TRANS : local_as_;
1504  openmsg.holdtime = state_machine_->GetConfiguredHoldTime();
1505  openmsg.identifier = ntohl(local_bgp_id_);
1506  BgpProto::OpenMessage::OptParam *opt_param =
1508 
1509  static const uint8_t cap_mp[][4] = {
1510  { 0, (uint8_t) BgpAf::FamilyToAfi(supported_families_[0]), 0,
1512  { 0, (uint8_t) BgpAf::FamilyToAfi(supported_families_[1]), 0,
1514  { 0, (uint8_t) BgpAf::FamilyToAfi(supported_families_[2]), 0,
1516  { 0, (uint8_t) BgpAf::FamilyToAfi(supported_families_[3]), 0,
1518  { 0, (uint8_t) BgpAf::FamilyToAfi(supported_families_[4]), 0,
1520  { 0, (uint8_t) BgpAf::FamilyToAfi(supported_families_[5]), 0,
1522  { 0, (uint8_t) BgpAf::FamilyToAfi(supported_families_[6]), 0,
1524  { 0, (uint8_t) BgpAf::FamilyToAfi(supported_families_[7]), 0,
1526  { 0, (uint8_t) BgpAf::FamilyToAfi(supported_families_[8]), 0,
1528  };
1529 
1530  static const FamilyToCapabilityMap family_to_cap_map = map_list_of
1531  (supported_families_[0], cap_mp[0])
1532  (supported_families_[1], cap_mp[1])
1533  (supported_families_[2], cap_mp[2])
1534  (supported_families_[3], cap_mp[3])
1535  (supported_families_[4], cap_mp[4])
1536  (supported_families_[5], cap_mp[5])
1537  (supported_families_[6], cap_mp[6])
1538  (supported_families_[7], cap_mp[7])
1539  (supported_families_[8], cap_mp[8]);
1540 
1541  // Add capabilities for configured address families.
1542  BOOST_FOREACH(const FamilyToCapabilityMap::value_type &val,
1543  family_to_cap_map) {
1544  if (!LookupFamily(val.first))
1545  continue;
1549  opt_param->capabilities.push_back(cap);
1550  }
1551 
1552  if (server_->enable_4byte_as()) {
1553  uint32_t asn = ntohl(local_as_);
1557  (const uint8_t *)(&asn), 4);
1558  opt_param->capabilities.push_back(cap);
1559  }
1560  peer_close_->AddGRCapabilities(opt_param);
1561  peer_close_->AddLLGRCapabilities(opt_param);
1562 
1563  if (opt_param->capabilities.size()) {
1564  openmsg.opt_params.push_back(opt_param);
1565  } else {
1566  delete opt_param;
1567  }
1568  uint8_t data[256];
1569  int result = BgpProto::Encode(&openmsg, data, sizeof(data));
1570  assert(result > BgpProto::kMinMessageSize);
1571  BGP_LOG_PEER(Message, this, SandeshLevel::SYS_INFO, BGP_LOG_FLAG_ALL,
1572  BGP_PEER_DIR_OUT, "Open " << openmsg.ToString());
1573  session->Send(data, result, NULL);
1574  inc_tx_open();
1575 }
1576 
1577 void BgpPeer::SendKeepalive(bool from_timer) {
1578  tbb::spin_mutex::scoped_lock lock(spin_mutex_);
1579 
1580  // Bail if there's no session for the peer anymore.
1581  if (!session_)
1582  return;
1583 
1584  BgpProto::Keepalive msg;
1585  uint8_t data[BgpProto::kMinMessageSize];
1586  int result = BgpProto::Encode(&msg, data, sizeof(data));
1587  assert(result == BgpProto::kMinMessageSize);
1588  SandeshLevel::type log_level = from_timer ? Sandesh::LoggingUtLevel() :
1589  SandeshLevel::SYS_INFO;
1590  BGP_LOG_PEER(Message, this, log_level, BGP_LOG_FLAG_SYSLOG,
1591  BGP_PEER_DIR_OUT, "Keepalive");
1592  send_ready_ = session_->Send(data, result, NULL);
1593  inc_tx_keepalive();
1594 }
1595 
1596 static bool SkipUpdateSend() {
1597  static bool init_;
1598  static bool skip_;
1599 
1600  if (init_) return skip_;
1601 
1602  skip_ = getenv("BGP_SKIP_UPDATE_SEND") != NULL;
1603  init_ = true;
1604 
1605  return skip_;
1606 }
1607 
1610  : origin_override(config.origin_override),
1611  origin(BgpAttr::OriginFromString(config.origin)) {
1612 }
1613 
1615  if (origin_override != rhs.origin_override) {
1616  return true;
1617  }
1618 
1619  // compare origin only if override is set
1620  if (origin_override && origin != rhs.origin) {
1621  return true;
1622  }
1623  return false;
1624 }
1625 
1626 //
1627 // Accumulate the message in the update buffer.
1628 // Flush the existing buffer if the message can't fit.
1629 // Note that FlushUpdateUnlocked clears the buffer.
1630 //
1631 bool BgpPeer::SendUpdate(const uint8_t *msg, size_t msgsize,
1632  const string *msg_str) {
1633  tbb::spin_mutex::scoped_lock lock(spin_mutex_);
1634  bool send_ready = true;
1635  if (buffer_.size() + msgsize > buffer_capacity_) {
1637  assert(buffer_.empty());
1638  }
1639  buffer_.insert(buffer_.end(), msg, msg + msgsize);
1640  inc_tx_update();
1641  return send_ready;
1642 }
1643 
1645  // Bail if the update buffer is empty.
1646  if (buffer_.empty())
1647  return true;
1648 
1649  // Bail if there's no session for the peer anymore.
1650  if (!session_) {
1651  buffer_.clear();
1652  return true;
1653  }
1654 
1655  if (!SkipUpdateSend()) {
1656  send_ready_ = session_->Send(buffer_.data(), buffer_.size(), NULL);
1657  buffer_.clear();
1658  if (send_ready_) {
1660  } else {
1662  }
1663  } else {
1664  send_ready_ = true;
1665  }
1666 
1667  if (!send_ready_) {
1668  BGP_LOG_PEER(Event, this, SandeshLevel::SYS_DEBUG, BGP_LOG_FLAG_ALL,
1669  BGP_PEER_DIR_NA, "Send blocked");
1670  }
1671  return send_ready_;
1672 }
1673 
1675  tbb::spin_mutex::scoped_lock lock(spin_mutex_);
1676  return FlushUpdateUnlocked();
1677 }
1678 
1680  return peer_close_->gr_params().notification();
1681 }
1682 
1683 // Check if GR Helper mode sould be attempted.
1684 bool BgpPeer::AttemptGRHelperMode(int code, int subcode) const {
1685  if (!code)
1686  return true;
1687 
1688  if (code == BgpProto::Notification::Cease &&
1689  (subcode == BgpProto::Notification::HardReset ||
1691  return false;
1692  }
1693 
1694  // If Peer supports Notification (N) bit, then attempt GR-Helper for all
1695  // other notifications, not otherwise.
1696  return notification();
1697 }
1698 
1700  int code, int subcode, const string &data) {
1701  tbb::spin_mutex::scoped_lock lock(spin_mutex_);
1702  session->SendNotification(code, subcode, data);
1703  state_machine_->set_last_notification_out(code, subcode, data);
1705 }
1706 
1708  peer_bgp_id_ = htonl(msg->identifier);
1709  capabilities_.clear();
1710  vector<BgpProto::OpenMessage::OptParam *>::const_iterator it;
1711  for (it = msg->opt_params.begin(); it < msg->opt_params.end(); ++it) {
1712  capabilities_.insert(capabilities_.end(), (*it)->capabilities.begin(),
1713  (*it)->capabilities.end());
1714  (*it)->capabilities.clear();
1715  }
1716 
1717  as4_supported_ = false;
1718  if (server_->enable_4byte_as()) {
1719  vector<BgpProto::OpenMessage::Capability *>::iterator c_it;
1720  for (c_it = capabilities_.begin(); c_it < capabilities_.end(); ++c_it) {
1721  if ((*c_it)->code ==BgpProto::OpenMessage::Capability::AS4Support) {
1722  as4_supported_ = true;
1723  break;
1724  }
1725  }
1726  }
1727  BgpPeerInfoData peer_info;
1728  peer_info.set_name(ToUVEKey());
1729  peer_info.set_peer_id(peer_bgp_id_);
1730 
1731  vector<string> families;
1732  vector<BgpProto::OpenMessage::Capability *>::iterator cap_it;
1733  for (cap_it = capabilities_.begin(); cap_it < capabilities_.end();
1734  ++cap_it) {
1735  if ((*cap_it)->code != BgpProto::OpenMessage::Capability::MpExtension)
1736  continue;
1737  uint8_t *data = (*cap_it)->capability.data();
1738  uint16_t afi = get_value(data, 2);
1739  uint8_t safi = get_value(data + 3, 1);
1740  Address::Family family = BgpAf::AfiSafiToFamily(afi, safi);
1741  if (family == Address::UNSPEC) {
1742  families.push_back(BgpAf::ToString(afi, safi));
1743  } else {
1744  families.push_back(Address::FamilyToString(family));
1745  }
1746  }
1747  peer_info.set_families(families);
1748 
1749  negotiated_families_.clear();
1750  for (int idx = Address::UNSPEC; idx < Address::NUM_FAMILIES; ++idx) {
1751  if (!family_attributes_list_[idx])
1752  continue;
1753  Address::Family family = static_cast<Address::Family>(idx);
1754  uint16_t afi;
1755  uint8_t safi;
1756  tie(afi, safi) = BgpAf::FamilyToAfiSafi(family);
1757  if (!MpNlriAllowed(afi, safi))
1758  continue;
1759  negotiated_families_.push_back(Address::FamilyToString(family));
1760  }
1761  sort(negotiated_families_.begin(), negotiated_families_.end());
1762  peer_info.set_negotiated_families(negotiated_families_);
1763 
1764  // Process GR/LLGR capabilities and close non-gracefully if any ongoing GR
1765  // needs be aborted.
1766  if (!peer_close_->SetGRCapabilities(&peer_info)) {
1767  BGP_LOG_PEER(Message, this, SandeshLevel::SYS_INFO, BGP_LOG_FLAG_ALL,
1768  BGP_PEER_DIR_IN, "Close non-gracefully");
1769  Close(false);
1770  return false;
1771  }
1772  return true;
1773 }
1774 
1775 // Reset capabilities stored inside peer structure.
1776 //
1777 // When open message is processed, we directly take the capabilities off the
1778 // open message and store inside the peer structure.
1779 //
1782  BgpPeerInfoData peer_info;
1783  peer_info.set_name(ToUVEKey());
1784  vector<string> families = vector<string>();
1785  peer_info.set_families(families);
1786  vector<string> negotiated_families = vector<string>();
1787  peer_info.set_negotiated_families(negotiated_families);
1788  peer_info.set_graceful_restart_families(vector<string>());
1789  BGPPeerInfoSend(peer_info);
1790 }
1791 
1792 bool BgpPeer::MpNlriAllowed(uint16_t afi, uint8_t safi) {
1793  vector<BgpProto::OpenMessage::Capability *>::iterator it;
1794  for (it = capabilities_.begin(); it < capabilities_.end(); ++it) {
1796  continue;
1797  uint8_t *data = (*it)->capability.data();
1798  uint16_t af_value = get_value(data, 2);
1799  uint8_t safi_value = get_value(data + 3, 1);
1800  if (afi == af_value && safi == safi_value) {
1801  return true;
1802  }
1803  }
1804  return false;
1805 }
1806 
1808  return as4_supported_;
1809 }
1810 
1811 template <typename TableT, typename PrefixT>
1813  const BgpMpNlri *nlri, BgpAttrPtr attr, uint32_t flags) {
1814  TableT *table = static_cast<TableT *>(rtinstance_->GetTable(family));
1815  assert(table);
1816 
1817  for (vector<BgpProtoPrefix *>::const_iterator it = nlri->nlri.begin();
1818  it != nlri->nlri.end(); ++it) {
1819  PrefixT prefix;
1820  BgpAttrPtr new_attr(attr);
1821  uint32_t label = 0;
1822  uint32_t l3_label = 0;
1823  int result = PrefixT::FromProtoPrefix(server_, **it,
1824  (oper == DBRequest::DB_ENTRY_ADD_CHANGE ? attr.get() : NULL),
1825  family, &prefix, &new_attr, &label, &l3_label);
1826  if (result) {
1829  "MP NLRI parse error for " <<
1830  Address::FamilyToString(family) << " route");
1831  continue;
1832  }
1833 
1834  DBRequest req;
1835  req.oper = oper;
1836  if (oper == DBRequest::DB_ENTRY_ADD_CHANGE) {
1837  req.data.reset(new typename TableT::RequestData(
1838  new_attr, flags, label, l3_label, 0));
1839  }
1840  req.key.reset(new typename TableT::RequestKey(prefix, this));
1841  table->Enqueue(&req);
1842  }
1843 }
1844 
1845 template <typename PrefixT>
1847  const BgpMpNlri *nlri, BgpAttrPtr attr, uint32_t flags) {
1848 
1849  for (vector<BgpProtoPrefix *>::const_iterator it = nlri->nlri.begin();
1850  it != nlri->nlri.end(); ++it) {
1851  PrefixT prefix;
1852  BgpAttrPtr new_attr(attr);
1853  uint32_t label = 0;
1854  uint32_t l3_label = 0;
1855  int result = PrefixT::FromProtoPrefix(server_, **it,
1856  (oper == DBRequest::DB_ENTRY_ADD_CHANGE ? attr.get() : NULL),
1857  family, &prefix, &new_attr, &label, &l3_label);
1858  if (result) {
1861  "MP NLRI parse error for " <<
1862  Address::FamilyToString(family) << " route");
1863  continue;
1864  }
1865 
1866  ProcessBgpaas(oper, prefix.addr(), prefix.prefixlen(), new_attr, flags);
1867  }
1868 }
1869 
1871  IpAddress addr, uint8_t addr_len, BgpAttrPtr attr, uint32_t flags) {
1872 
1873  if (rtinstance_->routing_instance_vxlan() == "") {
1874  return;
1875  }
1877  if (mgr == nullptr) {
1878  return;
1879  }
1880  RoutingInstance *vxlan_ri =
1882  if (vxlan_ri == nullptr) {
1883  return;
1884  }
1885  EvpnTable *table = static_cast<EvpnTable *>(vxlan_ri->GetTable(Address::EVPN));
1886  EvpnPrefix prefix_evpn(RouteDistinguisher::kZeroRd, addr, addr_len);
1887 
1888  DBRequest req;
1889  req.oper = oper;
1890  if (oper == DBRequest::DB_ENTRY_ADD_CHANGE) {
1891  req.data.reset(new EvpnTable::RequestData(attr, flags, 0, 0, 0));
1892  }
1893  else {
1894  req.data.reset(NULL);
1895  }
1896  req.key.reset(new EvpnTable::RequestKey(prefix_evpn, this));
1897  table->Enqueue(&req);
1898 }
1899 
1901  const BgpAttr *attr) const {
1902  uint32_t flags = resolve_paths_ ? BgpPath::ResolveNexthop : 0;
1903 
1904  // Check for OriginatorId loop in case we are an RR client.
1905  if (peer_type_ == BgpProto::IBGP &&
1906  attr->originator_id().to_ulong() == ntohl(local_bgp_id_)) {
1907  flags |= BgpPath::OriginatorIdLooped;
1908  }
1909 
1910  // Check for ClusterList loop in case we are an RR.
1911  if (server_->cluster_id() && attr->cluster_list() &&
1913  server_->cluster_id())) {
1914  flags |= BgpPath::ClusterListLooped;
1915  }
1916 
1917  if (!attr->as_path() && !attr->aspath_4byte())
1918  return flags;
1919 
1920  // Check whether neighbor has appended its AS to the AS_PATH.
1921  if ((PeerType() == BgpProto::EBGP) &&
1922  ((attr->as_path() && !attr->as_path()->path().AsLeftMostMatch(
1923  peer_as())) || (attr->aspath_4byte() &&
1924  !attr->aspath_4byte()->path().AsLeftMostMatch(peer_as())))) {
1925  flags |= BgpPath::NoNeighborAs;
1926  }
1927 
1928  // Check for AS_PATH loop.
1929  uint8_t max_loop_count = family_attributes_list_[family]->loop_count;
1930  if (attr->IsAsPathLoop(local_as_, max_loop_count))
1931  flags |= BgpPath::AsPathLooped;
1932 
1933  return flags;
1934 }
1935 
1936 uint32_t BgpPeer::GetLocalPrefFromMed(uint32_t med) const {
1937  if (peer_type_ != BgpProto::EBGP)
1938  return 0;
1939  if (!peer_is_control_node_)
1940  return 0;
1941  if (med == 0)
1942  return 0;
1943  if (med == 100)
1944  return 200;
1945  if (med == 200)
1946  return 100;
1947  return numeric_limits<uint32_t>::max() - med;
1948 }
1949 
1950 void BgpPeer::ProcessUpdate(const BgpProto::Update *msg, size_t msgsize) {
1951  BgpAttrPtr attr = server_->attr_db()->Locate(msg->path_attributes);
1952 
1953  uint32_t local_pref = GetLocalPrefFromMed(attr->med());
1954  if (local_pref) {
1955  attr = server_->attr_db()->ReplaceLocalPreferenceAndLocate(attr.get(),
1956  local_pref);
1957  }
1958 
1959  // Check if peer is marked to override the route origin attribute
1961  attr = server_->attr_db()->ReplaceOriginAndLocate(attr.get(),
1963  }
1964 
1965  if ((router_type_ == "bgpaas-client") ||
1966  (router_type_ == "bgpaas-server")) {
1967  attr = server_->attr_db()->ReplaceSubProtocolAndLocate(attr.get(),
1969  }
1970 
1971  uint32_t reach_count = 0, unreach_count = 0;
1972  RoutingInstance *instance = GetRoutingInstance();
1973  if (msg->nlri.size() || msg->withdrawn_routes.size()) {
1974  InetTable *table =
1975  static_cast<InetTable *>(instance->GetTable(Address::INET));
1976  if (!table) {
1978  "Cannot find inet table");
1979  return;
1980  }
1981 
1982  unreach_count += msg->withdrawn_routes.size();
1983  for (vector<BgpProtoPrefix *>::const_iterator it =
1984  msg->withdrawn_routes.begin(); it != msg->withdrawn_routes.end();
1985  ++it) {
1986  Ip4Prefix prefix;
1987  int result = Ip4Prefix::FromProtoPrefix((**it), &prefix);
1988  if (result) {
1991  "Withdrawn route parse error for inet route");
1992  continue;
1993  }
1994 
1995  if ((router_type_ == "bgpaas-client") ||
1996  (router_type_ == "bgpaas-server")) {
1998  prefix.prefixlen(), attr, 0);
1999  }
2000 
2001  DBRequest req;
2003  req.data.reset(NULL);
2004  req.key.reset(new InetTable::RequestKey(prefix, this));
2005  table->Enqueue(&req);
2006  }
2007 
2008  uint32_t flags = GetPathFlags(Address::INET, attr.get());
2009  reach_count += msg->nlri.size();
2010  for (vector<BgpProtoPrefix *>::const_iterator it = msg->nlri.begin();
2011  it != msg->nlri.end(); ++it) {
2012  Ip4Prefix prefix;
2013  int result = Ip4Prefix::FromProtoPrefix((**it), &prefix);
2014  if (result) {
2017  "NLRI parse error for inet route");
2018  continue;
2019  }
2020 
2021  DBRequest req;
2023  req.data.reset(new InetTable::RequestData(attr, flags, 0, 0, 0));
2024  req.key.reset(new InetTable::RequestKey(prefix, this));
2025  table->Enqueue(&req);
2026 
2027  if ((router_type_ == "bgpaas-client") ||
2028  (router_type_ == "bgpaas-server")) {
2030  prefix.prefixlen(), attr, flags);
2031  }
2032  }
2033  }
2034 
2035  for (vector<BgpAttribute *>::const_iterator ait =
2036  msg->path_attributes.begin();
2037  ait != msg->path_attributes.end(); ++ait) {
2039  if ((*ait)->code == BgpAttribute::MPReachNlri) {
2041  } else if ((*ait)->code == BgpAttribute::MPUnreachNlri) {
2043  } else {
2044  continue;
2045  }
2046 
2047  BgpMpNlri *nlri = static_cast<BgpMpNlri *>(*ait);
2048  assert(nlri);
2049  if (oper == DBRequest::DB_ENTRY_ADD_CHANGE) {
2050  reach_count += nlri->nlri.size();
2051  } else {
2052  unreach_count += nlri->nlri.size();
2053  }
2054 
2055  Address::Family family = BgpAf::AfiSafiToFamily(nlri->afi, nlri->safi);
2056  if (!IsFamilyNegotiated(family)) {
2059  "AFI "<< nlri->afi << " SAFI " << (int) nlri->safi <<
2060  " not allowed");
2061  continue;
2062  }
2063 
2064  // Handle EndOfRib marker.
2065  if (oper == DBRequest::DB_ENTRY_DELETE && nlri->nlri.empty()) {
2067  BGP_LOG_PEER(Message, this, SandeshLevel::SYS_INFO,
2069  "EndOfRib marker family " <<
2070  Address::FamilyToString(family) <<
2071  " size " << msgsize);
2072  ReceiveEndOfRIB(family, msgsize);
2073  return;
2074  }
2075 
2076  uint32_t flags = 0;
2077  if ((*ait)->code == BgpAttribute::MPReachNlri) {
2078  flags = GetPathFlags(family, attr.get());
2079  attr = GetMpNlriNexthop(nlri, attr);
2080  }
2081 
2082  switch (family) {
2083  case Address::INET:
2084  case Address::INETMPLS:
2085  ProcessNlri<InetTable, Ip4Prefix>(
2086  family, oper, nlri, attr, flags);
2087  if ((router_type_ == "bgpaas-client") ||
2088  (router_type_ == "bgpaas-server")) {
2089  ProcessNlriBgpaas<Ip4Prefix>(
2090  family, oper, nlri, attr, flags);
2091  }
2092  break;
2093  case Address::INETVPN:
2094  ProcessNlri<InetVpnTable, InetVpnPrefix>(
2095  family, oper, nlri, attr, flags);
2096  break;
2097  case Address::INET6:
2098  ProcessNlri<Inet6Table, Inet6Prefix>(
2099  family, oper, nlri, attr, flags);
2100  if ((router_type_ == "bgpaas-client") ||
2101  (router_type_ == "bgpaas-server")) {
2102  ProcessNlriBgpaas<Inet6Prefix>(
2103  family, oper, nlri, attr, flags);
2104  }
2105  break;
2106  case Address::INET6VPN:
2107  ProcessNlri<Inet6VpnTable, Inet6VpnPrefix>(
2108  family, oper, nlri, attr, flags);
2109  break;
2110  case Address::EVPN:
2111  ProcessNlri<EvpnTable, EvpnPrefix>(
2112  family, oper, nlri, attr, flags);
2113  break;
2114  case Address::ERMVPN:
2115  ProcessNlri<ErmVpnTable, ErmVpnPrefix>(
2116  family, oper, nlri, attr, flags);
2117  break;
2118  case Address::MVPN:
2119  ProcessNlri<MvpnTable, MvpnPrefix>(
2120  family, oper, nlri, attr, flags);
2121  break;
2122  case Address::RTARGET:
2123  ProcessNlri<RTargetTable, RTargetPrefix>(
2124  family, oper, nlri, attr, flags);
2125  break;
2126  default:
2127  break;
2128  }
2129  }
2130 
2131  inc_rx_route_reach(reach_count);
2132  inc_rx_route_unreach(unreach_count);
2136  "Update size " << msgsize <<
2137  " reach " << reach_count << " unreach " << unreach_count);
2138  }
2139 }
2140 const std::vector<std::string> BgpPeer::GetDefaultTunnelEncap(
2141  const Address::Family family) const {
2142  if (family_attributes_list_[family] == NULL)
2143  return std::vector<std::string>();
2144  return family_attributes_list_[family]->default_tunnel_encap_list;
2145 }
2146 
2148  ExtCommunityDB *extcomm_db,
2149  const BgpTable *table) const {
2150  if (!GetDefaultTunnelEncap(table->family()).empty()) {
2151  ExtCommunityPtr ext_community = attr->ext_community();
2152  bool tunnel_encap_found = false;
2153  if (ext_community) {
2154  for (ExtCommunity::ExtCommunityList::const_iterator iter =
2155  attr->ext_community()->communities().begin();
2156  iter != attr->ext_community()->communities().end();
2157  ++iter) {
2158  if (ExtCommunity::is_tunnel_encap(*iter)) {
2159  tunnel_encap_found = true;
2160  break;
2161  }
2162  }
2163  }
2164  // Set default tunnel encap since it is not in the path
2165  if (!ext_community || !tunnel_encap_found) {
2166  ExtCommunity::ExtCommunityList encap_list;
2167  BOOST_FOREACH(const string &encap_string,
2168  GetDefaultTunnelEncap(table->family())) {
2169  TunnelEncap tunnel_encap(encap_string);
2170  encap_list.push_back(tunnel_encap.GetExtCommunity());
2171  }
2172  ext_community =
2174  ext_community ? ext_community.get() : NULL, encap_list);
2175  attr->set_ext_community(ext_community);
2176  }
2177  }
2178 }
2179 
2180 
2181 void BgpPeer::UpdatePrimaryPathCount(int count, Address::Family family) const {
2182  primary_path_count_ += count;
2183  if (family == Address::UNSPEC)
2184  return;
2185  family_primary_path_count_[family] += count;
2186  uint32_t limit = 0;
2187  if (family_attributes_list_[family])
2188  limit = family_attributes_list_[family]->prefix_limit;
2189  if (limit && family_primary_path_count_[family] > limit)
2191 }
2192 
2193 void BgpPeer::StartPrefixLimitIdleTimer(uint32_t plim_idle_time_msecs) {
2194  prefix_limit_idle_timer_->Start(plim_idle_time_msecs,
2195  boost::bind(&BgpPeer::PrefixLimitIdleTimerExpired, this),
2196  boost::bind(&BgpPeer::PrefixLimitIdleTimerErrorHandler, this, _1, _2));
2197 }
2198 
2201 }
2202 
2205 }
2206 
2208  return false;
2209 }
2210 
2212  string error_message) {
2214  "Timer error: " << error_name << " " << error_message);
2215 }
2216 
2217 void BgpPeer::EndOfRibTimerErrorHandler(string error_name,
2218  string error_message) {
2220  "Timer error: " << error_name << " " << error_message);
2221 }
2222 
2224  CHECK_CONCURRENCY("bgp::StateMachine", "bgp::RTFilter", "bgp::Config");
2225 
2227  return;
2228  vpn_tables_registered_ = true;
2229 
2230  RoutingInstance *instance = GetRoutingInstance();
2231  vector<Address::Family> vpn_family_list = list_of
2233  (Address::MVPN);
2234  BOOST_FOREACH(Address::Family vpn_family, vpn_family_list) {
2235  if (!IsFamilyNegotiated(vpn_family))
2236  continue;
2237  BgpTable *table = instance->GetTable(vpn_family);
2238  BGP_LOG_PEER_TABLE(this, SandeshLevel::SYS_INFO, BGP_LOG_FLAG_TRACE,
2239  table, "Register peer with the table");
2240  Register(table, BuildRibExportPolicy(vpn_family));
2241  }
2242 }
2243 
2245  uint32_t timeout = GetEndOfRibReceiveTime(family);
2246 
2247  BGP_LOG_PEER(Message, this, SandeshLevel::SYS_INFO,
2249  "EndOfRib Receive Timer scheduled for family " <<
2250  Address::FamilyToString(family) <<
2251  " to fire after " << timeout << " second(s)");
2252  eor_receive_timer_[family]->Start(timeout * 1000,
2253  boost::bind(&BgpPeer::EndOfRibReceiveTimerExpired, this, family),
2254  boost::bind(&BgpPeer::EndOfRibTimerErrorHandler, this, _1, _2));
2255 }
2256 
2258  string error_message) {
2260  "Timer error: " << error_name << " " << error_message);
2261 }
2262 
2264  if (family == Address::RTARGET)
2266 
2267  // Fake reception of EoRs to exit from GR states and sweep all stale routes.
2268  close_manager_->ProcessEORMarkerReceived(family);
2269  return false;
2270 }
2271 
2273  if (!IsReady())
2274  return false;
2275 
2276  SendKeepalive(true);
2277 
2278  //
2279  // Start the timer again, by returning true
2280  //
2281  return true;
2282 }
2283 
2285  int keepalive_time_msecs = state_machine_->keepalive_time_msecs();
2286  if (keepalive_time_msecs <= 0)
2287  return;
2288 
2289  keepalive_timer_->Start(keepalive_time_msecs,
2290  boost::bind(&BgpPeer::KeepaliveTimerExpired, this),
2291  boost::bind(&BgpPeer::KeepaliveTimerErrorHandler, this, _1, _2));
2292 }
2293 
2295  tbb::spin_mutex::scoped_lock lock(spin_mutex_);
2296  if (session_ && send_ready_)
2298 }
2299 
2302 }
2303 
2305  tbb::spin_mutex::scoped_lock lock(spin_mutex_);
2306  return keepalive_timer_->running();
2307 }
2308 
2310  tbb::spin_mutex::scoped_lock lock(spin_mutex_);
2311  BGP_LOG_PEER(Event, this, SandeshLevel::SYS_DEBUG, BGP_LOG_FLAG_ALL,
2312  BGP_PEER_DIR_NA, "Send ready");
2313  send_ready_ = true;
2314  if (session_ != NULL)
2316 }
2317 
2319  tbb::spin_mutex::scoped_lock lock(spin_mutex_);
2320  assert(session_ == NULL);
2321  session_ = session;
2322 }
2323 
2325  tbb::spin_mutex::scoped_lock lock(spin_mutex_);
2326  if (session_) {
2327  session_->clear_peer();
2328  session_->set_observer(NULL);
2329  session_->Close();
2330  }
2331  session_ = NULL;
2332 }
2333 
2335  return session_;
2336 }
2337 
2338 string BgpPeer::BytesToHexString(const u_int8_t *msg, size_t size) {
2339  ostringstream out;
2340  char buf[4];
2341 
2342  for (size_t i = 0; i < size; i ++) {
2343  if (!(i % 32)) out << "\n";
2344  if (!(i % 4)) out << " 0x";
2345  snprintf(buf, sizeof(buf), "%02X", msg[i]);
2346  out << buf;
2347  }
2348 
2349  out << "\n";
2350 
2351  return out.str();
2352 }
2353 
2354 bool BgpPeer::ReceiveMsg(BgpSession *session, const u_int8_t *msg,
2355  size_t size) {
2356  ParseErrorContext ec;
2357  BgpProto::BgpMessage *minfo = BgpProto::Decode(msg, size, &ec,
2358  Is4ByteAsSupported());
2359 
2360  if (minfo == NULL) {
2361  BGP_TRACE_PEER_PACKET(this, msg, size, SandeshLevel::SYS_WARN);
2364  "Error while parsing message at " << ec.type_name);
2365  state_machine_->OnMessageError(session, &ec);
2366  return false;
2367  }
2368 
2369  // Tracing periodic keepalive packets is not necessary.
2370  if (minfo->type != BgpProto::KEEPALIVE)
2371  BGP_TRACE_PEER_PACKET(this, msg, size, Sandesh::LoggingUtLevel());
2372 
2373  state_machine_->OnMessage(session, minfo, size);
2374  return true;
2375 }
2376 
2377 //
2378 // Extract nexthop address from BgpMpNlri if appropriate and return updated
2379 // BgpAttrPtr. The original attribute is returned for cases where there's no
2380 // nexthop attribute in the BgpMpNlri.
2381 //
2383  bool update_nh = false;
2384  IpAddress addr;
2385 
2386  if (nlri->afi == BgpAf::IPv4) {
2387  if (nlri->safi == BgpAf::Mpls || nlri->safi == BgpAf::Unicast ||
2388  nlri->safi == BgpAf::RTarget || nlri->safi == BgpAf::MVpn) {
2389  Ip4Address::bytes_type bt = { { 0 } };
2390  copy(nlri->nexthop.begin(),
2391  nlri->nexthop.begin() + sizeof(bt), bt.begin());
2392  addr = Ip4Address(bt);
2393  update_nh = true;
2394  } else if (nlri->safi == BgpAf::Vpn) {
2395  Ip4Address::bytes_type bt = { { 0 } };
2396  size_t rdsize = RouteDistinguisher::kSize;
2397  copy(nlri->nexthop.begin() + rdsize,
2398  nlri->nexthop.begin() + rdsize + sizeof(bt), bt.begin());
2399  addr = Ip4Address(bt);
2400  update_nh = true;
2401  }
2402  } else if (nlri->afi == BgpAf::L2Vpn) {
2403  if (nlri->safi == BgpAf::EVpn) {
2404  Ip4Address::bytes_type bt = { { 0 } };
2405  copy(nlri->nexthop.begin(),
2406  nlri->nexthop.begin() + sizeof(bt), bt.begin());
2407  addr = Ip4Address(bt);
2408  update_nh = true;
2409  }
2410  } else if (nlri->afi == BgpAf::IPv6) {
2411  if (nlri->safi == BgpAf::Unicast) {
2412  // There could be either 1 or 2 v6 addresses in the nexthop field.
2413  // The first one is supposed to be global and the optional second
2414  // one, if present, is link local. We will be liberal and find the
2415  // global address, whether it's first or second. Further, if the
2416  // address is a v4-mapped v6 address, we use the corresponding v4
2417  // address as the nexthop.
2418  for (int idx = 0; idx < 2; ++idx) {
2419  Ip6Address::bytes_type bt = { { 0 } };
2420  if ((idx + 1) * sizeof(bt) > nlri->nexthop.size())
2421  break;
2422  copy(nlri->nexthop.begin() + idx * sizeof(bt),
2423  nlri->nexthop.begin() + (idx + 1) * sizeof(bt), bt.begin());
2424  Ip6Address v6_addr(bt);
2425  if (v6_addr.is_v4_mapped()) {
2426  addr = Address::V4FromV4MappedV6(v6_addr);
2427  update_nh = true;
2428  break;
2429  }
2430  if (!v6_addr.is_link_local()) {
2431  addr = v6_addr;
2432  update_nh = true;
2433  break;
2434  }
2435  }
2436  } else if (nlri->safi == BgpAf::Vpn) {
2437  Ip6Address::bytes_type bt = { { 0 } };
2438  size_t rdsize = RouteDistinguisher::kSize;
2439  copy(nlri->nexthop.begin() + rdsize,
2440  nlri->nexthop.begin() + rdsize + sizeof(bt), bt.begin());
2441  Ip6Address v6_addr(bt);
2442  if (v6_addr.is_v4_mapped()) {
2443  addr = Address::V4FromV4MappedV6(v6_addr);
2444  update_nh = true;
2445  }
2446  }
2447  }
2448 
2449  // Always update the nexthop in BgpAttr with MpReachNlri->nexthop.
2450  // NOP in cases <afi,safi> doesn't carry nexthop attribute.
2451  if (update_nh) {
2452  attr = server_->attr_db()->ReplaceNexthopAndLocate(attr.get(), addr);
2453  }
2454  return attr;
2455 }
2456 
2458  if (deleter_->IsDeleted())
2459  return;
2460  BGP_LOG_PEER(Config, this, SandeshLevel::SYS_INFO, BGP_LOG_FLAG_ALL,
2461  BGP_PEER_DIR_NA, "Received request for deletion");
2462  if (IsRouterTypeBGPaaS()) {
2464  } else {
2466  }
2467  deleter_->Delete();
2468 }
2469 
2471  if (!deleter_->IsDeleted())
2472  return;
2473  deleter_->RetryDelete();
2474 }
2475 
2478 }
2479 
2480 void BgpPeer::SetDataCollectionKey(BgpPeerInfo *peer_info) const {
2481  if (rtinstance_) {
2482  peer_info->set_domain(rtinstance_->name());
2483  } else {
2484  peer_info->set_domain(BgpConfigManager::kMasterInstance);
2485  }
2486 
2487  peer_info->set_ip_address(peer_key_.endpoint.address().to_string());
2488 }
2489 
2491  PeerProtoStats *proto_stats) {
2492  proto_stats->set_open(stats.open);
2493  proto_stats->set_keepalive(stats.keepalive);
2494  proto_stats->set_close(stats.close);
2495  proto_stats->set_update(stats.update);
2496  proto_stats->set_notification(stats.notification);
2497  proto_stats->set_total(stats.open + stats.keepalive + stats.close +
2498  stats.update + stats.notification);
2499 }
2500 
2502  PeerUpdateStats *rt_stats) {
2503  rt_stats->set_reach(stats.reach);
2504  rt_stats->set_unreach(stats.unreach);
2505  rt_stats->set_end_of_rib(stats.end_of_rib);
2506  rt_stats->set_total(stats.reach + stats.unreach + stats.end_of_rib);
2507 }
2508 
2509 static void FillSocketStats(const IPeerDebugStats::SocketStats &socket_stats,
2510  PeerSocketStats *peer_socket_stats) {
2511  peer_socket_stats->set_calls(socket_stats.calls);
2512  peer_socket_stats->set_bytes(socket_stats.bytes);
2513  if (socket_stats.calls) {
2514  peer_socket_stats->set_average_bytes(
2515  socket_stats.bytes/socket_stats.calls);
2516  }
2517  peer_socket_stats->set_blocked_count(socket_stats.blocked_count);
2518  ostringstream os;
2519  os << boost::posix_time::microseconds(long(socket_stats.blocked_duration_usecs));
2520  peer_socket_stats->set_blocked_duration(os.str());
2521  if (socket_stats.blocked_count) {
2522  os.str("");
2523  os << boost::posix_time::microseconds(
2524  socket_stats.blocked_duration_usecs/socket_stats.blocked_count);
2525  peer_socket_stats->set_average_blocked_duration(os.str());
2526  }
2527 }
2528 
2529 void BgpPeer::FillCloseInfo(BgpNeighborResp *resp) const {
2530  close_manager_->FillCloseInfo(resp);
2531 }
2532 
2533 void BgpPeer::FillBgpNeighborDebugState(BgpNeighborResp *bnr,
2534  const IPeerDebugStats *peer_stats) {
2535  bnr->set_last_state(peer_stats->last_state());
2536  bnr->set_last_event(peer_stats->last_event());
2537  bnr->set_last_error(peer_stats->last_error());
2538  bnr->set_last_state_at(peer_stats->last_state_change_at());
2539  bnr->set_flap_count(peer_stats->num_flaps());
2540  bnr->set_flap_time(peer_stats->last_flap());
2541 
2543  PeerProtoStats proto_stats;
2544  peer_stats->GetRxProtoStats(&stats);
2545  FillProtoStats(stats, &proto_stats);
2546  bnr->set_rx_proto_stats(proto_stats);
2547 
2548  peer_stats->GetTxProtoStats(&stats);
2549  FillProtoStats(stats, &proto_stats);
2550  bnr->set_tx_proto_stats(proto_stats);
2551 
2552  IPeerDebugStats::UpdateStats update_stats;
2553  PeerUpdateStats rt_stats;
2554  peer_stats->GetRxRouteUpdateStats(&update_stats);
2555  FillRouteUpdateStats(update_stats, &rt_stats);
2556  bnr->set_rx_update_stats(rt_stats);
2557 
2558  peer_stats->GetTxRouteUpdateStats(&update_stats);
2559  FillRouteUpdateStats(update_stats, &rt_stats);
2560  bnr->set_tx_update_stats(rt_stats);
2561 
2562  IPeerDebugStats::SocketStats socket_stats;
2563  PeerSocketStats peer_socket_stats;
2564 
2565  peer_stats->GetRxSocketStats(&socket_stats);
2566  FillSocketStats(socket_stats, &peer_socket_stats);
2567  bnr->set_rx_socket_stats(peer_socket_stats);
2568 
2569  peer_stats->GetTxSocketStats(&socket_stats);
2570  FillSocketStats(socket_stats, &peer_socket_stats);
2571  bnr->set_tx_socket_stats(peer_socket_stats);
2572 }
2573 
2574 void BgpPeer::FillBgpNeighborFamilyAttributes(BgpNeighborResp *nbr) const {
2575  vector<ShowBgpNeighborFamily> show_family_attributes_list;
2576  for (int idx = Address::UNSPEC; idx < Address::NUM_FAMILIES; ++idx) {
2577  if (!family_attributes_list_[idx])
2578  continue;
2579  ShowBgpNeighborFamily show_family_attributes;
2580  show_family_attributes.set_family(
2581  Address::FamilyToString(static_cast<Address::Family>(idx)));
2582  show_family_attributes.set_loop_count(
2583  family_attributes_list_[idx]->loop_count);
2584  show_family_attributes.set_prefix_limit(
2585  family_attributes_list_[idx]->prefix_limit);
2586  show_family_attributes.set_idle_timeout(
2587  family_attributes_list_[idx]->idle_timeout);
2588  if (!family_attributes_list_[idx]->gateway_address.is_unspecified()) {
2589  show_family_attributes.set_gateway_address(
2590  family_attributes_list_[idx]->gateway_address.to_string());
2591  }
2592  show_family_attributes_list.push_back(show_family_attributes);
2593  }
2594  nbr->set_family_attributes_list(show_family_attributes_list);
2595 }
2596 
2598  BgpNeighborResp *bnr, bool summary) const {
2599  bnr->set_instance_name(rtinstance_->name());
2600  bnr->set_peer(peer_basename_);
2601  bnr->set_deleted(IsDeleted());
2602  bnr->set_closed_at(UTCUsecToString(deleter_->delete_time_stamp_usecs()));
2603  bnr->set_admin_down(admin_down_);
2604  bnr->set_passive(passive_);
2605  bnr->set_as_override(as_override_);
2606  bnr->set_origin_override(origin_override_.origin_override);
2608  bnr->set_route_origin(BgpAttr::OriginToString(origin_override_.origin));
2609  } else {
2610  bnr->set_route_origin("-");
2611  }
2612  bnr->set_private_as_action(private_as_action_);
2613  bnr->set_peer_address(peer_address_string());
2614  bnr->set_peer_id(bgp_identifier_string());
2615  bnr->set_peer_asn(peer_as());
2616  bnr->set_peer_port(peer_port());
2617  bnr->set_transport_address(transport_address_string());
2618  bnr->set_encoding("BGP");
2619  bnr->set_peer_type(PeerType() == BgpProto::IBGP ? "internal" : "external");
2620  bnr->set_router_type(router_type_);
2621  bnr->set_state(state_machine_->StateName());
2622  bnr->set_local_address(server_->ToString());
2623  bnr->set_local_id(Ip4Address(ntohl(local_bgp_id_)).to_string());
2624  bnr->set_local_asn(local_as());
2625  bnr->set_cluster_id(Ip4Address(cluster_id_).to_string());
2626  bnr->set_negotiated_hold_time(state_machine_->hold_time());
2627  bnr->set_primary_path_count(GetPrimaryPathCount());
2628  bnr->set_task_instance(GetTaskInstance());
2629  bnr->set_send_ready(send_ready_);
2630  bnr->set_flap_count(peer_stats_->num_flaps());
2631  bnr->set_as4_supported(Is4ByteAsSupported());
2632  bnr->set_flap_time(peer_stats_->last_flap());
2633  bnr->set_auth_type(
2635  if (bsc->test_mode()) {
2636  bnr->set_auth_keys(auth_data_.KeysToStringDetail());
2637  }
2638 
2639  if (summary)
2640  return;
2641 
2642  bnr->set_configured_address_families(configured_families_);
2643  bnr->set_negotiated_address_families(negotiated_families_);
2644 
2645  peer_close_->FillNeighborInfo(bnr);
2646 
2647  bnr->set_configured_hold_time(state_machine_->GetConfiguredHoldTime());
2651  mgr->FillPeerMembershipInfo(this, bnr);
2652  bnr->set_routing_instances(vector<BgpNeighborRoutingInstance>());
2653  FillCloseInfo(bnr);
2654 }
2655 
2657  peer_stats_->proto_stats_[0].open++;
2658 }
2659 
2661  peer_stats_->proto_stats_[1].open++;
2662 }
2663 
2665  peer_stats_->proto_stats_[0].keepalive++;
2666 }
2667 
2668 uint64_t BgpPeer::get_rx_keepalive() const {
2669  return peer_stats_->proto_stats_[0].keepalive;
2670 }
2671 
2673  peer_stats_->proto_stats_[1].keepalive++;
2674 }
2675 
2676 uint64_t BgpPeer::get_tx_keepalive() const {
2677  return peer_stats_->proto_stats_[1].keepalive;
2678 }
2679 
2681  peer_stats_->proto_stats_[0].update++;
2682 }
2683 
2684 uint64_t BgpPeer::get_rx_update() const {
2685  return peer_stats_->proto_stats_[0].update;
2686 }
2687 
2689  peer_stats_->proto_stats_[1].update++;
2690 }
2691 
2692 uint64_t BgpPeer::get_tx_update() const {
2693  return peer_stats_->proto_stats_[1].update;
2694 }
2695 
2697  peer_stats_->proto_stats_[0].notification++;
2698 }
2699 
2701  return peer_stats_->proto_stats_[0].notification;
2702 }
2703 
2705  peer_stats_->proto_stats_[1].notification++;
2706 }
2707 
2709  peer_stats_->update_stats_[0].end_of_rib++;
2710 }
2711 
2712 uint64_t BgpPeer::get_rx_end_of_rib() const {
2713  return peer_stats_->update_stats_[0].end_of_rib;
2714 }
2715 
2717  peer_stats_->update_stats_[1].end_of_rib++;
2718 }
2719 
2720 uint64_t BgpPeer::get_tx_end_of_rib() const {
2721  return peer_stats_->update_stats_[1].end_of_rib;
2722 }
2723 
2724 void BgpPeer::inc_rx_route_reach(uint64_t count) {
2725  peer_stats_->update_stats_[0].reach += count;
2726 }
2727 
2729  return peer_stats_->update_stats_[0].reach;
2730 }
2731 
2733  return peer_stats_->update_stats_[1].reach;
2734 }
2735 
2736 void BgpPeer::inc_rx_route_unreach(uint64_t count) {
2737  peer_stats_->update_stats_[0].unreach += count;
2738 }
2739 
2741  return peer_stats_->update_stats_[0].unreach;
2742 }
2743 
2745  return peer_stats_->update_stats_[1].unreach;
2746 }
2747 
2749  return peer_stats_->update_stats_[0].reach +
2750  peer_stats_->update_stats_[0].unreach +
2751  peer_stats_->update_stats_[0].end_of_rib;
2752 }
2753 
2755  return peer_stats_->update_stats_[1].reach +
2756  peer_stats_->update_stats_[1].unreach +
2757  peer_stats_->update_stats_[1].end_of_rib;
2758 }
2759 
2761  peer_stats_->error_stats_.connect_error++;
2762 }
2763 
2765  peer_stats_->error_stats_.connect_timer++;
2766 }
2767 
2769  peer_stats_->error_stats_.hold_timer++;
2770 }
2771 
2773  peer_stats_->error_stats_.open_error++;
2774 }
2775 
2777  peer_stats_->error_stats_.update_error++;
2778 }
2779 
2780 uint64_t BgpPeer::get_connect_error() const {
2781  return peer_stats_->error_stats_.connect_error;
2782 }
2783 
2785  return peer_stats_->error_stats_.connect_timer;
2786 }
2787 
2789  return peer_stats_->error_stats_.hold_timer;
2790 }
2791 
2792 uint64_t BgpPeer::get_open_error() const {
2793  return peer_stats_->error_stats_.open_error;
2794 }
2795 
2796 uint64_t BgpPeer::get_update_error() const {
2797  return peer_stats_->error_stats_.update_error;
2798 }
2799 
2800 uint64_t BgpPeer::get_socket_reads() const {
2802  peer_stats_->GetRxSocketStats(&stats);
2803  return stats.calls;
2804 }
2805 
2806 uint64_t BgpPeer::get_socket_writes() const {
2808  peer_stats_->GetTxSocketStats(&stats);
2809  return stats.calls;
2810 }
2811 
2812 string BgpPeer::last_flap_at() const {
2813  if (last_flap_) {
2815  } else {
2816  return "";
2817  }
2818 }
2819 
2821  flap_count_++;
2824 
2825  BgpPeerInfoData peer_info;
2826  peer_info.set_name(ToUVEKey());
2827  PeerFlapInfo flap_info;
2828  flap_info.set_flap_count(flap_count_);
2829  flap_info.set_flap_time(last_flap_);
2830  peer_info.set_flap_info(flap_info);
2831  BGPPeerInfoSend(peer_info);
2832 
2833  PeerFlapData peer_flap_data;
2834  peer_flap_data.set_name(ToUVEKey());
2835  peer_flap_data.set_flap_info(flap_info);
2836  assert(!peer_flap_data.get_name().empty());
2837  BGP_UVE_SEND2(PeerFlap, peer_flap_data, "ObjectBgpPeer");
2838 }
2839 
2841  flap_count_ = 0;
2842  last_flap_ = 0;
2843 
2844  BgpPeerInfoData peer_info;
2845  peer_info.set_name(ToUVEKey());
2846  PeerFlapInfo flap_info;
2847  peer_info.set_flap_info(flap_info);
2848  BGPPeerInfoSend(peer_info);
2849 
2850  PeerFlapData peer_flap_data;
2851  peer_flap_data.set_name(ToUVEKey());
2852  peer_flap_data.set_flap_info(flap_info);
2853  assert(!peer_flap_data.get_name().empty());
2854  BGP_UVE_SEND2(PeerFlap, peer_flap_data, "ObjectBgpPeer");
2855 }
2856 
2857 // Ignore if the peer is IBGP and a BGPaaS client since we do not support that
2858 // combination. i.e, allow any EBGP session or any non BGPaaS-client session.
2860  return PeerType() != BgpProto::IBGP || router_type() != "bgpaas-client";
2861 }
2862 
2863 // Update control DSCP
2864 void BgpPeer::DSCPUpdateCallback(uint8_t dscp_value) {
2865  if ((session_ != NULL) && (dscp_value != 0xFF)) {
2866  session_->SetDscpSocketOption(dscp_value);
2867  }
2868 }
boost::asio::ip::address_v6 Ip6Address
Definition: address.h:15
boost::asio::ip::address IpAddress
Definition: address.h:13
boost::asio::ip::address_v4 Ip4Address
Definition: address.h:14
std::vector< BgpAttribute * > BgpAttrSpec
Definition: bgp_attr.h:822
boost::intrusive_ptr< const BgpAttr > BgpAttrPtr
Definition: bgp_attr.h:997
#define AS_TRANS
Definition: bgp_common.h:23
uint32_t as_t
Definition: bgp_common.h:21
#define BGP_LOG_FLAG_ALL
Definition: bgp_log.h:44
#define BGP_LOG_FLAG_SYSLOG
Definition: bgp_log.h:42
#define BGP_LOG_PEER(type, peer, level, flags, dir, arg)
Definition: bgp_log.h:159
#define BGP_LOG_WARNING_STR(obj, flags, arg)
Definition: bgp_log.h:107
#define BGP_LOG_PEER_WARNING(type, peer, flags, dir, arg)
Definition: bgp_log.h:182
#define BGP_PEER_DIR_IN
Definition: bgp_log.h:139
#define BGP_LOG_PEER_TABLE(peer, level, flags, tbl, arg)
Definition: bgp_log.h:205
#define BGP_UVE_SEND2(type, object, arg)
Definition: bgp_log.h:52
#define BGP_PEER_DIR_NA
Definition: bgp_log.h:140
#define BGP_LOG_PEER_NOTICE(type, peer, flags, dir, arg)
Definition: bgp_log.h:170
#define BGP_TRACE_PEER_PACKET(peer, msg, size, level)
Definition: bgp_log.h:310
#define BGP_LOG_FLAG_TRACE
Definition: bgp_log.h:43
#define BGP_UVE_SEND(type, object)
Definition: bgp_log.h:46
#define BGP_LOG_PEER_CRITICAL(type, peer, flags, dir, arg)
Definition: bgp_log.h:194
#define BGP_PEER_DIR_OUT
Definition: bgp_log.h:138
#define BGP_LOG_STR(obj, level, flags, arg)
Definition: bgp_log.h:89
static void FillSocketStats(const IPeerDebugStats::SocketStats &socket_stats, PeerSocketStats *peer_socket_stats)
Definition: bgp_peer.cc:2509
static void FillProtoStats(const IPeerDebugStats::ProtoStats &stats, PeerProtoStats *proto_stats)
Definition: bgp_peer.cc:2490
static void FillRouteUpdateStats(const IPeerDebugStats::UpdateStats &stats, PeerUpdateStats *rt_stats)
Definition: bgp_peer.cc:2501
static bool SkipUpdateSend()
Definition: bgp_peer.cc:1596
Family
Definition: address.h:24
@ NUM_FAMILIES
Definition: address.h:35
@ INET
Definition: address.h:26
@ EVPN
Definition: address.h:31
@ INET6VPN
Definition: address.h:29
@ RTARGET
Definition: address.h:30
@ ERMVPN
Definition: address.h:32
@ INET6
Definition: address.h:27
@ INETVPN
Definition: address.h:28
@ MVPN
Definition: address.h:33
@ INETMPLS
Definition: address.h:34
@ UNSPEC
Definition: address.h:25
static Family FamilyFromString(const std::string &family)
Definition: address.cc:54
static Ip4Address V4FromV4MappedV6(const Ip6Address &v6_address)
Definition: address.cc:291
static std::string FamilyToString(Family fmly)
Definition: address.cc:63
const AsPath4ByteSpec & path() const
Definition: bgp_aspath.h:285
const AsPathSpec & path() const
Definition: bgp_aspath.h:127
bool Empty() const
Definition: bgp_config.cc:106
AuthenticationKeyChain::const_iterator const_iterator
Definition: bgp_config.h:48
std::vector< std::string > KeysToStringDetail() const
Definition: bgp_config.cc:143
std::string KeyTypeToString() const
Definition: bgp_config.cc:114
iterator begin()
Definition: bgp_config.h:50
KeyType key_type() const
Definition: bgp_config.h:70
@ RTarget
Definition: bgp_af.h:30
@ EVpn
Definition: bgp_af.h:28
@ Unicast
Definition: bgp_af.h:25
@ MVpn
Definition: bgp_af.h:27
@ Vpn
Definition: bgp_af.h:29
@ Mpls
Definition: bgp_af.h:26
static std::pair< uint16_t, uint8_t > FamilyToAfiSafi(Address::Family family)
Definition: bgp_af.cc:130
static Afi FamilyToAfi(Address::Family family)
Definition: bgp_af.cc:159
static Safi FamilyToSafi(Address::Family family)
Definition: bgp_af.cc:188
@ L2Vpn
Definition: bgp_af.h:21
@ IPv4
Definition: bgp_af.h:19
@ IPv6
Definition: bgp_af.h:20
static Address::Family AfiSafiToFamily(uint16_t afi, uint8_t safi)
Definition: bgp_af.cc:71
static std::string ToString(uint16_t afi, uint8_t safi)
Definition: bgp_af.cc:14
BgpAttrPtr ReplaceLocalPreferenceAndLocate(const BgpAttr *attr, uint32_t local_pref)
Definition: bgp_attr.cc:1368
BgpAttrPtr ReplaceNexthopAndLocate(const BgpAttr *attr, const IpAddress &addr)
Definition: bgp_attr.cc:1435
BgpAttrPtr ReplaceSubProtocolAndLocate(const BgpAttr *attr, const std::string &sbp)
Definition: bgp_attr.cc:1418
BgpAttrPtr ReplaceOriginAndLocate(const BgpAttr *attr, BgpAttrOrigin::OriginType origin)
Definition: bgp_attr.cc:1336
const AsPath * as_path() const
Definition: bgp_attr.h:901
static std::string OriginToString(BgpAttrOrigin::OriginType origin)
Definition: bgp_attr.cc:1109
const ClusterList * cluster_list() const
Definition: bgp_attr.h:909
int IsAsPathLoop(as_t asn, uint8_t max_loop_count=0) const
Definition: bgp_attr.cc:1228
const ExtCommunity * ext_community() const
Definition: bgp_attr.h:917
const AsPath4Byte * aspath_4byte() const
Definition: bgp_attr.h:904
void set_ext_community(ExtCommunityPtr extcomm)
Definition: bgp_attr.cc:1012
const Ip4Address & originator_id() const
Definition: bgp_attr.h:897
static const int kDefaultPort
Definition: bgp_config.h:780
static const char * kMasterInstance
Definition: bgp_config.h:778
uint8_t control_dscp() const
Definition: bgp_config.h:718
void RegisterRibIn(IPeer *peer, BgpTable *table)
virtual void Register(IPeer *peer, BgpTable *table, const RibExportPolicy &policy, int instance_id=-1)
void FillPeerMembershipInfo(const IPeer *peer, BgpNeighborResp *resp) const
uint32_t GetRibOutQueueDepth(const IPeer *peer, const BgpTable *table) const
AddressFamilyList GetAddressFamilies() const
Definition: bgp_config.cc:283
const OriginOverrideConfig & origin_override() const
Definition: bgp_config.h:273
uint32_t cluster_id() const
Definition: bgp_config.h:195
uint16_t source_port() const
Definition: bgp_config.h:219
const AuthenticationData & auth_data() const
Definition: bgp_config.h:244
uint32_t local_identifier() const
Definition: bgp_config.h:236
std::string router_type() const
Definition: bgp_config.h:222
const IpAddress & gateway_address(Address::Family family) const
Definition: bgp_config.cc:262
uint32_t peer_as() const
Definition: bgp_config.h:198
std::string private_as_action() const
Definition: bgp_config.h:190
bool admin_down() const
Definition: bgp_config.h:181
uint8_t loop_count() const
Definition: bgp_config.h:230
const FamilyAttributesList & family_attributes_list() const
Definition: bgp_config.h:253
uint32_t local_as() const
Definition: bgp_config.h:233
int hold_time() const
Definition: bgp_config.h:227
bool as_override() const
Definition: bgp_config.h:187
bool passive() const
Definition: bgp_config.h:184
TypePtr Locate(Type *attr)
@ NoNeighborAs
Definition: bgp_path.h:23
@ ClusterListLooped
Definition: bgp_path.h:31
@ AsPathLooped
Definition: bgp_path.h:22
@ OriginatorIdLooped
Definition: bgp_path.h:26
@ ResolveNexthop
Definition: bgp_path.h:27
virtual void Destroy()
Definition: bgp_peer.cc:187
virtual bool MayDelete() const
Definition: bgp_peer.cc:169
DeleteActor(BgpPeer *peer)
Definition: bgp_peer.cc:164
virtual void Shutdown()
Definition: bgp_peer.cc:182
virtual void GetRxRouteUpdateStats(UpdateStats *stats) const
Definition: bgp_peer.cc:109
virtual uint64_t num_flaps() const
Definition: bgp_peer.cc:97
virtual string last_event() const
Definition: bgp_peer.cc:87
virtual void GetRxProtoStats(ProtoStats *stats) const
Definition: bgp_peer.cc:101
virtual void GetTxSocketStats(IPeerDebugStats::SocketStats *stats) const
Definition: bgp_peer.cc:125
virtual string last_state_change_at() const
Definition: bgp_peer.cc:79
ProtoStats proto_stats_[2]
Definition: bgp_peer.cc:158
virtual string ToString() const
Definition: bgp_peer.cc:72
ErrorStats error_stats_
Definition: bgp_peer.cc:157
virtual void GetRxErrorStats(RxErrorStats *stats) const
Definition: bgp_peer.cc:145
virtual void GetTxProtoStats(ProtoStats *stats) const
Definition: bgp_peer.cc:105
virtual void UpdateTxReachRoute(uint64_t count)
Definition: bgp_peer.cc:140
virtual void GetRxRouteStats(RxRouteStats *stats) const
Definition: bgp_peer.cc:148
virtual void GetRxSocketStats(IPeerDebugStats::SocketStats *stats) const
Definition: bgp_peer.cc:117
virtual void Clear()
Definition: bgp_peer.cc:63
BgpPeer * peer_
Definition: bgp_peer.cc:156
virtual string last_flap() const
Definition: bgp_peer.cc:92
virtual string last_state() const
Definition: bgp_peer.cc:76
virtual string last_error() const
Definition: bgp_peer.cc:83
PeerStats(BgpPeer *peer)
Definition: bgp_peer.cc:56
UpdateStats update_stats_[2]
Definition: bgp_peer.cc:159
virtual void UpdateTxUnreachRoute(uint64_t count)
Definition: bgp_peer.cc:136
virtual void GetTxRouteUpdateStats(UpdateStats *stats) const
Definition: bgp_peer.cc:113
Timer * prefix_limit_idle_timer_
Definition: bgp_peer.h:480
virtual bool IsXmppPeer() const
Definition: bgp_peer.cc:1210
bool admin_down_
Definition: bgp_peer.h:511
bool as4_supported_
Definition: bgp_peer.h:522
uint64_t get_rx_notification() const
Definition: bgp_peer.cc:2700
static const int kRouteTargetEndOfRibTimeSecs
Definition: bgp_peer.h:86
bool PrefixLimitIdleTimerRunning() const
Definition: bgp_peer.cc:2203
uint64_t get_tx_route_unreach() const
Definition: bgp_peer.cc:2744
static const int kEndOfRibSendRetryTime
Definition: bgp_peer.h:85
uint32_t GetEndOfRibReceiveTime(Address::Family family) const
Definition: bgp_peer.cc:314
bool InstallAuthKeys()
Definition: bgp_peer.cc:841
virtual bool CanUseMembershipManager() const
Definition: bgp_peer.cc:421
void clear_session()
Definition: bgp_peer.cc:2324
void inc_rx_route_unreach(uint64_t count)
Definition: bgp_peer.cc:2736
void RegisterToVpnTables()
Definition: bgp_peer.cc:2223
virtual bool FlushUpdate()
Definition: bgp_peer.cc:1674
static const size_t kMinBufferCapacity
Definition: bgp_peer.h:87
const std::string peer_address_string() const
Definition: bgp_peer.h:162
virtual BgpProto::BgpPeerType PeerType() const
Definition: bgp_peer.h:209
virtual bool MpNlriAllowed(uint16_t afi, uint8_t safi)
Definition: bgp_peer.cc:1792
virtual const std::string GetStateName() const
Definition: bgp_peer.cc:1335
virtual time_t GetEorSendTimerElapsedTime() const
Definition: bgp_peer.cc:310
virtual bool ProcessSession() const
Definition: bgp_peer.cc:2859
uint32_t PeerAddress() const
Definition: bgp_peer.h:161
void RoutingInstanceCallback(const std::string &vrf_name, int op)
Definition: bgp_peer.cc:778
boost::scoped_ptr< PeerStats > peer_stats_
Definition: bgp_peer.h:538
RoutingInstance * GetRoutingInstance()
Definition: bgp_peer.h:203
BgpProto::BgpPeerType peer_type_
Definition: bgp_peer.h:534
void CustomClose()
Definition: bgp_peer.cc:1250
StateMachine * state_machine()
Definition: bgp_peer.h:327
KeyType inuse_authkey_type_
Definition: bgp_peer.h:549
virtual const std::string & ToUVEKey() const
Definition: bgp_peer.h:102
virtual bool IsInGRTimerWaitState() const
Definition: bgp_peer.cc:1317
void LogInstallAuthKeys(const std::string &socket_name, const std::string &oper, const AuthenticationKey &auth_key, KeyType key_type)
Definition: bgp_peer.cc:917
uint64_t get_connect_error() const
Definition: bgp_peer.cc:2780
boost::scoped_ptr< StateMachine > state_machine_
Definition: bgp_peer.h:535
uint64_t last_flap_
Definition: bgp_peer.h:545
uint64_t get_rx_keepalive() const
Definition: bgp_peer.cc:2668
BgpServer * server_
Definition: bgp_peer.h:464
std::string BytesToHexString(const u_int8_t *msg, size_t size)
Definition: bgp_peer.cc:2338
Timer * eor_send_timer_[Address::NUM_FAMILIES]
Definition: bgp_peer.h:508
bool as_override_
Definition: bgp_peer.h:514
void inc_tx_end_of_rib()
Definition: bgp_peer.cc:2716
bool IsRouterTypeBGPaaS() const
Definition: bgp_peer.h:359
BgpAttrPtr GetMpNlriNexthop(BgpMpNlri *nlri, BgpAttrPtr attr)
Definition: bgp_peer.cc:2382
void SetSessionSocketAuthKey(TcpSession *session)
Definition: bgp_peer.cc:893
void StopKeepaliveTimerUnlocked()
Definition: bgp_peer.cc:2300
void ClearConfig()
Definition: bgp_peer.cc:1161
void Close(bool graceful)
Definition: bgp_peer.cc:1268
std::vector< std::string > configured_families_
Definition: bgp_peer.h:532
void DeleteRTargets(as_t as)
Definition: bgp_peer.cc:754
std::string router_type_
Definition: bgp_peer.h:471
uint32_t local_bgp_id_
Definition: bgp_peer.h:528
const BgpNeighborConfig * config_
Definition: bgp_peer.h:475
std::atomic< int > membership_req_pending_
Definition: bgp_peer.h:519
TcpSession::Endpoint endpoint() const
Definition: bgp_peer.h:172
uint16_t hold_time_
Definition: bgp_peer.h:525
void inc_rx_update()
Definition: bgp_peer.cc:2680
void ASNUpdateCallback(as_t old_asn, as_t old_local_asn)
Definition: bgp_peer.cc:767
virtual int GetPrimaryPathCount() const
Definition: bgp_peer.h:323
bool IsCloseInProgress() const
Definition: bgp_peer.cc:1321
void inc_update_error()
Definition: bgp_peer.cc:2776
size_t GetBufferCapacity() const
Definition: bgp_peer.cc:656
void ProcessNlriBgpaas(Address::Family family, DBRequest::DBOperation oper, const BgpMpNlri *nlri, BgpAttrPtr attr, uint32_t flags)
Definition: bgp_peer.cc:1846
std::string transport_address_string() const
Definition: bgp_peer.cc:1230
void EndOfRibTimerErrorHandler(std::string error_name, std::string error_message)
Definition: bgp_peer.cc:2217
bool send_ready_
Definition: bgp_peer.h:510
void increment_flap_count()
Definition: bgp_peer.cc:2820
virtual bool IsReady() const
Definition: bgp_peer.cc:1206
bool ProcessFamilyAttributesConfig(const BgpNeighborConfig *config)
Definition: bgp_peer.cc:957
void reset_flap_count()
Definition: bgp_peer.cc:2840
bool IsDeleted() const
Definition: bgp_peer.cc:1313
uint16_t peer_port_
Definition: bgp_peer.h:468
uint64_t get_tx_keepalive() const
Definition: bgp_peer.cc:2676
std::string GetInuseAuthKeyValue() const
Definition: bgp_peer.cc:913
int membership_req_pending() const
Definition: bgp_peer.h:367
int instance_op_
Definition: bgp_peer.h:552
virtual void UpdateCloseRouteStats(Address::Family family, const BgpPath *old_path, uint32_t path_flags) const
Definition: bgp_peer.cc:1292
std::string uve_key_str_
Definition: bgp_peer.h:474
void ManagedDelete()
Definition: bgp_peer.cc:2457
std::string peer_name_
Definition: bgp_peer.h:469
virtual void ProcessPathTunnelEncapsulation(const BgpPath *path, BgpAttr *attr, ExtCommunityDB *extcomm_db, const BgpTable *table) const
Definition: bgp_peer.cc:2147
bool defer_close_
Definition: bgp_peer.h:520
std::string local_bgp_identifier_string() const
Definition: bgp_peer.cc:1218
virtual BgpServer * server()
Definition: bgp_peer.h:158
const std::string & peer_name() const
Definition: bgp_peer.h:169
void FillCloseInfo(BgpNeighborResp *resp) const
Definition: bgp_peer.cc:2529
virtual bool send_ready() const
Definition: bgp_peer.h:230
virtual void SetDataCollectionKey(BgpPeerInfo *peer_info) const
Definition: bgp_peer.cc:2480
void inc_connect_timer_expired()
Definition: bgp_peer.cc:2764
void ResetCapabilities()
Definition: bgp_peer.cc:1780
void ReceiveEndOfRIB(Address::Family family, size_t msgsize)
Definition: bgp_peer.cc:270
void inc_connect_error()
Definition: bgp_peer.cc:2760
bool EndOfRibReceiveTimerExpired(Address::Family family)
Definition: bgp_peer.cc:2263
void inc_tx_open()
Definition: bgp_peer.cc:2660
bool ProcessAuthKeyChainConfig(const BgpNeighborConfig *config)
Definition: bgp_peer.cc:830
void Clear(int subcode)
Definition: bgp_peer.cc:1305
RibExportPolicy BuildRibExportPolicy(Address::Family family) const
Definition: bgp_peer.cc:243
bool ResumeClose()
Definition: bgp_peer.cc:463
boost::scoped_ptr< BgpPeerClose > peer_close_
Definition: bgp_peer.h:536
uint64_t get_rx_end_of_rib() const
Definition: bgp_peer.cc:2712
std::string peer_basename_
Definition: bgp_peer.h:470
uint32_t peer_bgp_id_
Definition: bgp_peer.h:529
void SendKeepalive(bool from_timer)
Definition: bgp_peer.cc:1577
std::vector< BgpProto::OpenMessage::Capability * > capabilities_
Definition: bgp_peer.h:524
void PrefixLimitIdleTimerErrorHandler(std::string error_name, std::string error_message)
Definition: bgp_peer.cc:2211
virtual bool SendUpdate(const uint8_t *msg, size_t msgsize, const std::string *msg_str)
void inc_rx_route_reach(uint64_t count)
Definition: bgp_peer.cc:2724
std::atomic< int > primary_path_count_
Definition: bgp_peer.h:542
RoutingInstance * rtinstance_
Definition: bgp_peer.h:465
void StopPrefixLimitIdleTimer()
Definition: bgp_peer.cc:2199
uint64_t get_socket_reads() const
Definition: bgp_peer.cc:2800
bool FlushUpdateUnlocked()
Definition: bgp_peer.cc:1644
virtual bool MembershipPathCallback(DBTablePartBase *tpart, BgpRoute *route, BgpPath *path)
Definition: bgp_peer.cc:458
StateMachine::State GetState() const
Definition: bgp_peer.cc:1331
const std::vector< std::string > & negotiated_families() const
Definition: bgp_peer.h:343
void KeepaliveTimerErrorHandler(std::string error_name, std::string error_message)
Definition: bgp_peer.cc:2257
BgpPeerKey peer_key_
Definition: bgp_peer.h:467
uint64_t get_tx_route_reach() const
Definition: bgp_peer.cc:2732
TaskTrigger trigger_
Definition: bgp_peer.h:479
virtual const std::string & ToString() const
Definition: bgp_peer.h:101
void BGPPeerInfoSend(const BgpPeerInfoData &peer_info) const
Definition: bgp_peer.cc:416
RouteTargetList rtargets_
Definition: bgp_peer.h:550
std::map< Address::Family, const uint8_t * > FamilyToCapabilityMap
Definition: bgp_peer.h:387
virtual int GetTotalPathCount() const
Definition: bgp_peer.h:314
bool KeepaliveTimerExpired()
Definition: bgp_peer.cc:2272
boost::scoped_ptr< DeleteActor > deleter_
Definition: bgp_peer.h:539
BgpSession * session()
Definition: bgp_peer.cc:2334
void inc_tx_notification()
Definition: bgp_peer.cc:2704
AuthenticationData auth_data_
Definition: bgp_peer.h:547
virtual bool IsServerStartingUp() const
Definition: bgp_peer.cc:319
static const size_t kMaxBufferCapacity
Definition: bgp_peer.h:88
static const std::vector< Address::Family > supported_families_
Definition: bgp_peer.h:463
virtual uint32_t bgp_identifier() const
Definition: bgp_peer.cc:1222
void BGPaaSAddRTarget(as_t as, BgpTable *table, BgpAttrPtr attr, RouteTargetList::const_iterator it)
Definition: bgp_peer.cc:713
void SendNotification(BgpSession *, int code, int subcode=0, const std::string &data=std::string())
Definition: bgp_peer.cc:1699
std::atomic< int > total_path_count_
Definition: bgp_peer.h:541
uint64_t flap_count_
Definition: bgp_peer.h:543
void set_session(BgpSession *session)
Definition: bgp_peer.cc:2318
void SendOpen(TcpSession *session)
Definition: bgp_peer.cc:1501
virtual bool ReceiveMsg(BgpSession *session, const u_int8_t *msg, size_t size)
Definition: bgp_peer.cc:2354
void MembershipRequestCallback(BgpTable *table)
Definition: bgp_peer.cc:430
void RegisterAllTables()
Definition: bgp_peer.cc:1431
void ProcessBgpaas(DBRequest::DBOperation oper, IpAddress addr, uint8_t addr_len, BgpAttrPtr attr, uint32_t flags)
Definition: bgp_peer.cc:1870
void inc_hold_timer_expired()
Definition: bgp_peer.cc:2768
uint64_t get_rx_route_total() const
Definition: bgp_peer.cc:2748
uint32_t cluster_id_
Definition: bgp_peer.h:516
boost::scoped_ptr< PeerCloseManager > close_manager_
Definition: bgp_peer.h:537
void ClearListenSocketAuthKey()
Definition: bgp_peer.cc:887
virtual void UpdatePrimaryPathCount(int count, Address::Family family) const
Definition: bgp_peer.cc:2181
std::atomic< uint32_t > family_primary_path_count_[Address::NUM_FAMILIES]
Definition: bgp_peer.h:531
uint64_t get_open_error() const
Definition: bgp_peer.cc:2792
BgpSession * session_
Definition: bgp_peer.h:505
bool CheckPrefixLimits()
Definition: bgp_peer.cc:933
uint64_t get_socket_writes() const
Definition: bgp_peer.cc:2806
time_t eor_send_timer_start_time_
Definition: bgp_peer.h:509
virtual const std::vector< std::string > GetDefaultTunnelEncap(const Address::Family family) const
Definition: bgp_peer.cc:2140
virtual uint32_t local_bgp_identifier() const
Definition: bgp_peer.cc:1214
void StartPrefixLimitIdleTimer(uint32_t plim_idle_time_msecs)
Definition: bgp_peer.cc:2193
std::string gateway_address_string(Address::Family family) const
Definition: bgp_peer.cc:1239
uint64_t get_tx_update() const
Definition: bgp_peer.cc:2692
bool SetCapabilities(const BgpProto::OpenMessage *msg)
Definition: bgp_peer.cc:1707
void FillNeighborInfo(const BgpSandeshContext *bsc, BgpNeighborResp *bnr, bool summary) const
Definition: bgp_peer.cc:2597
uint64_t get_rx_route_reach() const
Definition: bgp_peer.cc:2728
void StartKeepaliveTimer()
Definition: bgp_peer.cc:2294
OriginOverride origin_override_
Definition: bgp_peer.h:517
uint64_t get_hold_timer_expired() const
Definition: bgp_peer.cc:2788
uint32_t GetPathFlags(Address::Family family, const BgpAttr *attr) const
Definition: bgp_peer.cc:1900
void inc_rx_notification()
Definition: bgp_peer.cc:2696
std::string router_type() const
Definition: bgp_peer.h:171
bool KeepaliveTimerRunning()
Definition: bgp_peer.cc:2304
TaskTrigger prefix_limit_trigger_
Definition: bgp_peer.h:481
size_t buffer_capacity_
Definition: bgp_peer.h:503
uint64_t total_flap_count_
Definition: bgp_peer.h:544
void FillBgpNeighborFamilyAttributes(BgpNeighborResp *nbr) const
Definition: bgp_peer.cc:2574
uint64_t flap_count() const
Definition: bgp_peer.h:250
BgpSession * CreateSession()
Definition: bgp_peer.cc:1339
void RetryDelete()
Definition: bgp_peer.cc:2470
tbb::spin_mutex spin_mutex_
Definition: bgp_peer.h:502
std::string last_flap_at() const
Definition: bgp_peer.cc:2812
void ResetInuseAuthKeyInfo()
Definition: bgp_peer.cc:874
void inc_tx_update()
Definition: bgp_peer.cc:2688
int asn_listener_id_
Definition: bgp_peer.h:551
virtual void SendEndOfRIB(Address::Family family)
Definition: bgp_peer.cc:404
std::vector< std::string > negotiated_families_
Definition: bgp_peer.h:533
void inc_rx_end_of_rib()
Definition: bgp_peer.cc:2708
as_t local_as_
Definition: bgp_peer.h:526
FamilyAttributesList family_attributes_list_
Definition: bgp_peer.h:530
void SetInuseAuthKeyInfo(const AuthenticationKey &key, KeyType type)
Definition: bgp_peer.cc:869
void ProcessUpdate(const BgpProto::Update *msg, size_t msgsize=0)
Definition: bgp_peer.cc:1950
BgpTable * GetRTargetTable()
Definition: bgp_peer.cc:693
void inc_rx_keepalive()
Definition: bgp_peer.cc:2664
BgpAttrPtr GetRouteTargetRouteAttr() const
Definition: bgp_peer.cc:703
uint64_t get_rx_route_unreach() const
Definition: bgp_peer.cc:2740
virtual bool notification() const
Definition: bgp_peer.cc:1679
virtual time_t GetRTargetTableLastUpdatedTimeStamp() const
Definition: bgp_peer.cc:327
AuthenticationKey inuse_auth_key_
Definition: bgp_peer.h:548
virtual ~BgpPeer()
Definition: bgp_peer.cc:624
void BGPaaSDeleteRTarget(as_t as, BgpTable *table, RouteTargetList::const_iterator it)
Definition: bgp_peer.cc:741
bool graceful_close_
Definition: bgp_peer.h:521
bool EndOfRibSendTimerExpired(Address::Family family)
Definition: bgp_peer.cc:331
bool PrefixLimitIdleTimerExpired()
Definition: bgp_peer.cc:2207
virtual void BindLocalEndpoint(BgpSession *session)
Definition: bgp_peer.cc:814
void inc_rx_open()
Definition: bgp_peer.cc:2656
uint64_t get_rx_update() const
Definition: bgp_peer.cc:2684
bool passive_
Definition: bgp_peer.h:512
virtual IPeerDebugStats * peer_stats()
Definition: bgp_peer.cc:1297
Timer * eor_receive_timer_[Address::NUM_FAMILIES]
Definition: bgp_peer.h:507
std::vector< uint8_t > buffer_
Definition: bgp_peer.h:504
virtual uint32_t GetOutputQueueDepth(Address::Family family) const
Definition: bgp_peer.cc:305
void SetListenSocketAuthKey(const AuthenticationKey &auth_key, KeyType key_type)
Definition: bgp_peer.cc:879
void ProcessNlri(Address::Family family, DBRequest::DBOperation oper, const BgpMpNlri *nlri, BgpAttrPtr attr, uint32_t flags)
Definition: bgp_peer.cc:1812
void inc_open_error()
Definition: bgp_peer.cc:2772
void Initialize()
Definition: bgp_peer.cc:651
void DSCPUpdateCallback(uint8_t dscp_value)
Definition: bgp_peer.cc:2864
as_t peer_as() const
Definition: bgp_peer.h:185
void PostCloseRelease()
Definition: bgp_peer.cc:1186
bool AcceptSession(BgpSession *session)
Definition: bgp_peer.cc:1368
const BgpNeighborConfig * config() const
Definition: bgp_peer.h:214
void SetSendReady()
Definition: bgp_peer.cc:2309
uint64_t get_tx_route_total() const
Definition: bgp_peer.cc:2754
TcpSession::Endpoint endpoint_
Definition: bgp_peer.h:466
virtual void SendEndOfRIBActual(Address::Family family)
Definition: bgp_peer.cc:279
void ConfigUpdate(const BgpNeighborConfig *config)
Definition: bgp_peer.cc:991
uint64_t get_tx_end_of_rib() const
Definition: bgp_peer.cc:2720
Timer * keepalive_timer_
Definition: bgp_peer.h:506
std::vector< BgpPeerFamilyAttributes * > FamilyAttributesList
Definition: bgp_peer.h:388
int GetTaskInstance() const
Definition: bgp_peer.cc:2476
bool IsCloseGraceful() const
Definition: bgp_peer.cc:323
bool IsFamilyNegotiated(Address::Family family)
Definition: bgp_peer.cc:1173
virtual bool Is4ByteAsSupported() const
Definition: bgp_peer.cc:1807
void NotifyEstablished(bool established)
Definition: bgp_peer.cc:797
uint64_t get_update_error() const
Definition: bgp_peer.cc:2796
void ProcessEndpointConfig(const BgpNeighborConfig *config)
Definition: bgp_peer.cc:979
bool GetBestAuthKey(AuthenticationKey *auth_key, KeyType *key_type) const
Definition: bgp_peer.cc:818
PeerCloseManager * close_manager()
Definition: bgp_peer.h:356
uint64_t get_connect_timer_expired() const
Definition: bgp_peer.cc:2784
as_t peer_as_
Definition: bgp_peer.h:527
void StartEndOfRibReceiveTimer(Address::Family family)
Definition: bgp_peer.cc:2244
int dscp_listener_id_
Definition: bgp_peer.h:546
virtual IPeerClose * peer_close()
Definition: bgp_peer.cc:1284
virtual bool CheckSplitHorizon(uint32_t cluster_id=0, uint32_t ribout_cid=0) const
Definition: bgp_peer.cc:676
virtual void StartKeepaliveTimerUnlocked()
Definition: bgp_peer.cc:2284
std::string bgp_identifier_string() const
Definition: bgp_peer.cc:1226
bool AttemptGRHelperMode(int code, int subcode) const
Definition: bgp_peer.cc:1684
string private_as_action_
Definition: bgp_peer.h:515
uint16_t peer_port() const
Definition: bgp_peer.h:166
bool resolve_paths_
Definition: bgp_peer.h:513
bool vpn_tables_registered_
Definition: bgp_peer.h:523
void SetSessionSocketOptionDscp(TcpSession *session)
Definition: bgp_peer.cc:902
std::string to_str_
Definition: bgp_peer.h:473
int index_
Definition: bgp_peer.h:478
void Register(BgpTable *table, const RibExportPolicy &policy)
Definition: bgp_peer.cc:1380
virtual void SetAdminState(bool down, int subcode=BgpProto::Notification::AdminShutdown)
Definition: bgp_peer.cc:1356
as_t local_as() const
Definition: bgp_peer.h:184
bool LookupFamily(Address::Family family)
Definition: bgp_peer.h:198
bool peer_is_control_node_
Definition: bgp_peer.h:472
static void FillBgpNeighborDebugState(BgpNeighborResp *bnr, const IPeerDebugStats *peer)
Definition: bgp_peer.cc:2533
virtual void TriggerPrefixLimitCheck() const
Definition: bgp_peer.cc:987
void inc_tx_keepalive()
Definition: bgp_peer.cc:2672
uint32_t GetLocalPrefFromMed(uint32_t med) const
Definition: bgp_peer.cc:1936
void AddRTargets(as_t as)
Definition: bgp_peer.cc:726
LifetimeActor * deleter()
Definition: bgp_peer.cc:1166
BgpPeer(BgpServer *server, RoutingInstance *instance, const BgpNeighborConfig *config)
Definition: bgp_peer.cc:469
@ KEEPALIVE
Definition: bgp_proto.h:25
static const int kMinMessageSize
Definition: bgp_proto.h:440
static BgpMessage * Decode(const uint8_t *data, size_t size, ParseErrorContext *ec=NULL, bool as4=false)
Definition: bgp_proto.cc:2115
static int Encode(const BgpMessage *msg, uint8_t *data, size_t size, EncodeOffsets *offsets=NULL, bool as4=false)
Definition: bgp_proto.cc:2135
void decrement_deleting_count()
Definition: bgp_server.h:232
uint32_t cluster_id() const
Definition: bgp_server.h:210
boost::asio::io_context * ioservice()
Definition: bgp_server.cc:690
bool enable_4byte_as() const
Definition: bgp_server.cc:734
uint32_t GetEndOfRibSendTime() const
Definition: bgp_server.cc:726
void IncrementUpBgpaasPeerCount()
Definition: bgp_server.h:262
void DecrementUpPeerCount()
Definition: bgp_server.h:255
void UnregisterPeer(BgpPeer *peer)
Definition: bgp_server.cc:610
RoutingInstanceMgr * routing_instance_mgr()
Definition: bgp_server.h:106
void IncrementUpPeerCount()
Definition: bgp_server.h:252
uint32_t bgp_identifier() const
Definition: bgp_server.h:215
uint32_t GetEndOfRibReceiveTime() const
Definition: bgp_server.cc:722
void DecrementUpBgpaasPeerCount()
Definition: bgp_server.h:265
void decrement_deleting_bgpaas_count()
Definition: bgp_server.h:240
BgpGlobalQosConfig * global_qos()
Definition: bgp_server.h:301
void UnregisterASNUpdateCallback(int listener)
Definition: bgp_server.cc:881
void UnregisterDSCPUpdateCallback(int listener)
Definition: bgp_server.cc:926
virtual std::string ToString() const
Definition: bgp_server.cc:564
int RegisterDSCPUpdateCallback(DSCPUpdateCb cb)
Definition: bgp_server.cc:910
bool IsServerStartingUp() const
Definition: bgp_server.cc:730
as_t local_autonomous_system() const
Definition: bgp_server.h:214
BgpAttrDB * attr_db()
Definition: bgp_server.h:187
const std::string & localname() const
Definition: bgp_server.cc:686
time_t GetRTargetTableLastUpdatedTimeStamp() const
Definition: bgp_server.cc:1214
BgpSessionManager * session_manager()
Definition: bgp_server.h:101
int RegisterASNUpdateCallback(ASNUpdateCb callback)
Definition: bgp_server.cc:865
BgpMembershipManager * membership_mgr()
Definition: bgp_server.h:179
void increment_deleting_count()
Definition: bgp_server.h:231
void increment_deleting_bgpaas_count()
Definition: bgp_server.h:239
virtual TcpSession * CreateSession()
void SendNotification(int code, int subcode, const std::string &data=std::string())
Definition: bgp_session.cc:112
void clear_peer()
Definition: bgp_session.cc:138
void set_peer(BgpPeer *peer)
Definition: bgp_session.cc:128
void LocatePathResolver()
Definition: bgp_table.cc:1083
virtual Address::Family family() const =0
const ClusterListSpec & cluster_list() const
Definition: bgp_attr.h:229
static bool end_of_rib_computed()
bool Enqueue(DBRequest *req)
Definition: db_table.cc:220
ExtCommunityPtr ReplaceTunnelEncapsulationAndLocate(const ExtCommunity *src, const ExtCommunity::ExtCommunityList &tunnel_encaps)
Definition: community.cc:900
static bool is_tunnel_encap(const ExtCommunityValue &val)
Definition: community.h:368
std::vector< ExtCommunityValue > ExtCommunityList
Definition: community.h:155
const ExtCommunityList & communities() const
Definition: community.h:182
virtual void UpdateRouteStats(Address::Family family, const BgpPath *old_path, uint32_t path_flags) const =0
virtual std::string last_error() const =0
virtual uint64_t num_flaps() const =0
virtual void GetRxRouteUpdateStats(UpdateStats *stats) const =0
virtual std::string last_state() const =0
virtual std::string last_state_change_at() const =0
virtual void GetRxProtoStats(ProtoStats *stats) const =0
virtual std::string last_flap() const =0
virtual void GetTxSocketStats(SocketStats *stats) const =0
virtual void GetTxRouteUpdateStats(UpdateStats *stats) const =0
virtual std::string last_event() const =0
virtual void GetTxProtoStats(ProtoStats *stats) const =0
virtual void GetRxSocketStats(SocketStats *stats) const =0
int prefixlen() const
Definition: inet_route.h:27
static int FromProtoPrefix(const BgpProtoPrefix &proto_prefix, Ip4Prefix *prefix)
Definition: inet_route.cc:15
Ip4Address addr() const
Definition: inet_route.h:24
virtual void DestroyIPeer(IPeer *ipeer)
static const size_t kSize
Definition: rd.h:13
static RouteDistinguisher kZeroRd
Definition: rd.h:14
RoutingInstance * GetRoutingInstance(const std::string &name)
RoutingInstance * GetDefaultRoutingInstance()
int RegisterInstanceOpCallback(RoutingInstanceCb cb)
const std::string & name() const
const std::string & routing_instance_vxlan() const
PeerManager * peer_manager()
const RouteTargetList & GetImportList() const
BgpTable * GetTable(Address::Family fmly)
static SandeshLevel::type LoggingLevel()
Definition: cpp/sandesh.h:223
static SandeshLevel::type LoggingUtLevel()
Definition: cpp/sandesh.h:224
const std::string last_notification_in_error() const
const std::string & last_event() const
const std::string last_state_change_at() const
const std::string & LastStateName() const
The TaskScheduler keeps track of what tasks are currently schedulable. When a task is enqueued it is ...
Definition: task.h:304
int GetTaskId(const std::string &name)
Definition: task.cc:861
static TaskScheduler * GetInstance()
Definition: task.cc:554
int HardwareThreadCount()
Definition: task.h:402
bool IsSet() const
Definition: task_trigger.h:43
int SetListenSocketMd5Option(uint32_t peer_ip, const std::string &md5_password)
Definition: tcp_server.cc:519
const io::SocketStats & GetSocketStats() const
Definition: tcp_session.h:158
virtual Socket * socket() const
Definition: tcp_session.h:82
int SetMd5SocketOption(uint32_t peer_ip, const std::string &md5_password)
Definition: tcp_session.cc:560
void set_observer(EventObserver observer)
Definition: tcp_session.cc:219
boost::asio::ip::tcp::endpoint Endpoint
Definition: tcp_session.h:58
Endpoint remote_endpoint() const
Definition: tcp_session.h:131
virtual bool Send(const uint8_t *data, size_t size, size_t *sent)
Definition: tcp_session.cc:429
int SetDscpSocketOption(uint8_t value)
Definition: tcp_session.cc:570
void Close()
Definition: tcp_session.cc:355
static bool DeleteTimer(Timer *Timer)
Definition: timer.cc:221
static Timer * CreateTimer(boost::asio::io_context &service, const std::string &name, int task_id=Timer::GetTimerTaskId(), int task_instance=Timer::GetTimerInstanceId(), bool delete_on_completion=false)
Definition: timer.cc:200
Definition: timer.h:57
bool Cancel()
Definition: timer.cc:149
bool running() const
Definition: timer.h:89
bool Start(int time, Handler handler, ErrorHandler error_handler=NULL)
Definition: timer.cc:107
bool Reschedule(int time)
Definition: timer.cc:136
const bytes_type & GetExtCommunity() const
Definition: tunnel_encap.h:28
boost::intrusive_ptr< const ExtCommunity > ExtCommunityPtr
Definition: community.h:450
static void UpdateStats(FlowEvent *event, FlowStats *stats)
Definition: flow_proto.cc:785
Event
Definition: http_client.h:29
uint8_t type
Definition: load_balance.h:2
static uint64_t get_value(const uint8_t *data, int size)
Definition: parse_object.h:39
const string MatchProtocolToString(MatchProtocol::MatchProtocolType protocol)
bool set_synchronize(const SetType *set1, const SetType *set2, AddFunctor add_fn, DelFunctor del_fn)
Definition: set_util.h:21
static const std::string integerToString(const NumberType &num)
Definition: string_util.h:19
bool AsLeftMostMatch(as_t as) const
Definition: bgp_aspath.cc:296
bool AsLeftMostMatch(as2_t as) const
Definition: bgp_aspath.cc:34
std::string value
Definition: bgp_config.h:35
std::vector< std::string > default_tunnel_encap_list
Definition: bgp_config.h:99
uint8_t safi
Definition: bgp_attr.h:308
uint16_t afi
Definition: bgp_attr.h:307
std::vector< BgpProtoPrefix * > nlri
Definition: bgp_attr.h:311
std::vector< uint8_t > nexthop
Definition: bgp_attr.h:309
IpAddress gateway_address
Definition: bgp_peer.h:58
BgpPeerFamilyAttributes(const BgpNeighborConfig *config, const BgpFamilyAttributesConfig &family_config)
Definition: bgp_peer.cc:222
std::vector< std::string > default_tunnel_encap_list
Definition: bgp_peer.h:59
boost::asio::ip::tcp::endpoint endpoint
Definition: bgp_peer_key.h:24
OriginOverride(const BgpNeighborConfig::OriginOverrideConfig &config)
Definition: bgp_peer.cc:1608
bool operator!=(const OriginOverride &rhs) const
Definition: bgp_peer.cc:1614
BgpAttrOrigin::OriginType origin
Definition: bgp_peer.h:384
MessageType type
Definition: bgp_proto.h:53
std::vector< Capability * > capabilities
Definition: bgp_proto.h:217
virtual const std::string ToString() const
Definition: bgp_proto.cc:280
std::vector< OptParam * > opt_params
Definition: bgp_proto.h:219
std::vector< BgpAttribute * > path_attributes
Definition: bgp_proto.h:435
std::vector< BgpProtoPrefix * > withdrawn_routes
Definition: bgp_proto.h:434
std::vector< BgpProtoPrefix * > nlri
Definition: bgp_proto.h:436
bool test_mode() const
Definition: bgp_sandesh.h:61
bool ClusterListLoop(uint32_t cluster_id) const
Definition: bgp_attr.cc:223
DBOperation oper
Definition: db_table.h:42
@ DB_ENTRY_DELETE
Definition: db_table.h:39
@ DB_ENTRY_ADD_CHANGE
Definition: db_table.h:38
std::unique_ptr< DBRequestKey > key
Definition: db_table.h:48
std::unique_ptr< DBRequestData > data
Definition: db_table.h:49
uint64_t blocked_duration_usecs
Definition: ipeer.h:120
std::string type_name
Definition: parse_object.h:88
void SetRemovePrivatePolicy(bool all, bool replace, bool peer_loop_check)
std::atomic< uint64_t > write_calls
Definition: io_utils.h:23
std::atomic< uint64_t > write_blocked_duration_usecs
Definition: io_utils.h:28
std::atomic< uint64_t > read_bytes
Definition: io_utils.h:21
std::atomic< uint64_t > write_blocked
Definition: io_utils.h:27
std::atomic< uint64_t > read_calls
Definition: io_utils.h:20
std::atomic< uint64_t > write_bytes
Definition: io_utils.h:24
#define CHECK_CONCURRENCY(...)
static std::string UTCUsecToString(uint64_t tstamp)
Definition: time_util.h:54
static time_t UTCTimestamp()
Definition: time_util.h:23
static boost::posix_time::ptime UTCUsecToPTime(uint64_t tusec)
Definition: time_util.h:38
static uint64_t UTCTimestampUsec()
Definition: time_util.h:13
int STLSortedCompare(InputIterator first1, InputIterator last1, InputIterator first2, InputIterator last2, CompareOp op)
Definition: util.h:78
void STLDeleteValues(Container *container)
Definition: util.h:101