OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
peer_close_manager.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3  */
4 
6 
7 
8 #include <list>
9 #include <map>
10 
11 #include <boost/foreach.hpp>
12 
13 #include "base/task_annotations.h"
14 #include "bgp/bgp_log.h"
15 #include "bgp/bgp_membership.h"
16 #include "bgp/bgp_peer_types.h"
17 #include "bgp/bgp_route.h"
18 #include "bgp/bgp_server.h"
20 #include "net/community_type.h"
21 
22 #define PEER_CLOSE_MANAGER_LOG(msg) \
23  BGP_LOG_PEER(Event, peer_close_->peer(), SandeshLevel::SYS_INFO, \
24  BGP_LOG_FLAG_ALL, BGP_PEER_DIR_NA, \
25  "PeerCloseManager: State " << GetStateName(state_) << \
26  ", MembershipState: " << GetMembershipStateName(membership_state_) << \
27  ", MembershipReqPending: " << membership_req_pending_ << \
28  ", CloseAgain?: " << (close_again_ ? "Yes" : "No") << ": " << msg);
29 
30 #define PEER_CLOSE_MANAGER_TABLE_LOG(msg) \
31  BGP_LOG_PEER_TABLE(peer_close_->peer(), SandeshLevel::SYS_INFO, \
32  BGP_LOG_FLAG_ALL, table, \
33  "PeerCloseManager: State " << GetStateName(state_) << \
34  ", MembershipState: " << GetMembershipStateName(membership_state_) << \
35  ", MembershipReqPending: " << membership_req_pending_ << \
36  ", CloseAgain?: " << (close_again_ ? "Yes" : "No") << ": " << msg);
37 
38 #define MOVE_TO_STATE(state) \
39  do { \
40  assert(state_ != state); \
41  PEER_CLOSE_MANAGER_LOG("Move to state " << GetStateName(state)); \
42  state_ = state; \
43  } while (false)
44 
45 // Create an instance of PeerCloseManager with back reference to parent IPeer
47  boost::asio::io_context *io_service) :
48  peer_close_(peer_close), gr_timer_(NULL),
49  event_queue_(new WorkQueue<Event *>(
50  TaskScheduler::GetInstance()->GetTaskId(
51  peer_close_->GetTaskName()),
52  peer_close_->GetTaskInstance(),
53  boost::bind(&PeerCloseManager::EventCallback, this, _1))),
54  state_(NONE), close_again_(false), graceful_(true), gr_elapsed_(0),
55  llgr_elapsed_(0), membership_state_(MEMBERSHIP_NONE) {
56  stats_.init++;
59  "Graceful Restart Timer");
60 }
61 
62 // Create an instance of PeerCloseManager with back reference to parent IPeer
64  peer_close_(peer_close), gr_timer_(NULL),
65  event_queue_(new WorkQueue<Event *>(
66  TaskScheduler::GetInstance()->GetTaskId(
67  peer_close_->GetTaskName()),
68  peer_close_->GetTaskInstance(),
69  boost::bind(&PeerCloseManager::EventCallback, this, _1))),
70  state_(NONE), close_again_(false), graceful_(true), gr_elapsed_(0),
71  llgr_elapsed_(0), membership_state_(MEMBERSHIP_NONE) {
72  stats_.init++;
74  if (peer_close->peer() && peer_close->peer()->server()) {
75  gr_timer_ =
76  TimerManager::CreateTimer(*peer_close->peer()->server()->ioservice(),
77  "Graceful Restart Timer");
78  }
79 }
80 
82  event_queue_->Shutdown();
84 }
85 
86 std::string PeerCloseManager::GetStateName(State state) const {
87  switch (state) {
88  case NONE:
89  return "NONE";
90  case GR_TIMER:
91  return "GR_TIMER";
92  case STALE:
93  return "STALE";
94  case LLGR_STALE:
95  return "LLGR_STALE";
96  case LLGR_TIMER:
97  return "LLGR_TIMER";
98  case SWEEP:
99  return "SWEEP";
100  case DELETE:
101  return "DELETE";
102  }
103  assert(false);
104  return "";
105 }
106 
108  MembershipState state) const {
109  switch (state) {
110  case MEMBERSHIP_NONE:
111  return "NONE";
112  case MEMBERSHIP_IN_USE:
113  return "IN_USE";
114  case MEMBERSHIP_IN_WAIT:
115  return "IN_WAIT";
116  }
117  assert(false);
118  return "";
119 }
120 
121 std::string PeerCloseManager::GetEventName(EventType eventType) const {
122  switch (eventType) {
123  case EVENT_NONE:
124  return "NONE";
125  case CLOSE:
126  return "CLOSE";
127  case EOR_RECEIVED:
128  return "EOR_RECEIVED";
129  case MEMBERSHIP_REQUEST:
130  return "MEMBERSHIP_REQUEST";
132  return "MEMBERSHIP_REQUEST_COMPLETE_CALLBACK";
133  case TIMER_CALLBACK:
134  return "TIMER_CALLBACK";
135  }
136 
137  return "";
138 }
139 
141  PEER_CLOSE_MANAGER_LOG("Enqueued event " <<
142  GetEventName(event->event_type) <<
143  ", graceful " << event->graceful <<
144  ", family " << Address::FamilyToString(event->family));
145  event_queue_->Enqueue(event);
146 }
147 
148 // Trigger closure of an IPeer
149 //
150 // Graceful close_state_: NONE
151 // RibIn Stale Marking and Ribout deletion close_state_: STALE
152 // StateMachine restart and GR timer start close_state_: GR_TIMER
153 //
154 // Peer IsReady() in GR timer callback (or via reception of all EoRs)
155 // RibIn Sweep and Ribout Generation close_state_: SWEEP
156 // MembershipRequestCallback close_state_: NONE
157 //
158 // Peer not IsReady() in GR timer callback
159 // If LLGR supported close_state_: LLGR_STALE
160 // RibIn Stale marking with LLGR_STALE community close_state_: LLGR_TIMER
161 //
162 // Peer not IsReady() in LLGR timer callback
163 // RibIn Delete close_state_: DELETE
164 // MembershipRequestCallback close_state_: NONE
165 //
166 // Peer IsReady() in LLGR timer callback (or via reception of all EoRs)
167 // RibIn Sweep close_state_: SWEEP
168 // MembershipRequestCallback close_state_: NONE
169 //
170 // If LLGR is not supported
171 // RibIn Delete close_state_: DELETE
172 // MembershipRequestCallback close_state_: NONE
173 //
174 // Close() call during any state other than NONE and DELETE
175 // Cancel GR timer and restart GR Closure all over again
176 //
177 // NonGraceful close_state_ = * (except DELETE)
178 // A. RibIn deletion and Ribout deletion close_state_ = DELETE
179 // B. MembershipRequestCallback => Peers delete/StateMachine restart
180 // close_state_ = NONE
181 //
182 // If Close is restarted, account for GR timer's elapsed time.
183 //
184 // Use graceful as true to close gracefully.
185 void PeerCloseManager::Close(bool graceful) {
186  EnqueueEvent(new Event(CLOSE, graceful));
187 }
188 
190  // Note down non-graceful close trigger. Once non-graceful closure is
191  // triggered, it should remain so until close process is complete. Further
192  // graceful closure calls until then should remain non-graceful.
193  graceful_ &= event->graceful;
194  CloseInternal();
195 }
196 
198  stats_.close++;
199 
200  // Ignore nested closures
201  if (close_again_) {
202  PEER_CLOSE_MANAGER_LOG("Nested close calls ignored");
203  return;
204  }
205 
206  switch (state_) {
207  case NONE:
209  ProcessClosure();
210  break;
211 
212  case GR_TIMER:
213  PEER_CLOSE_MANAGER_LOG("Nested close: Restart GR");
214  close_again_ = true;
215  stats_.nested++;
217  CloseComplete();
218  break;
219 
220  case LLGR_TIMER:
221  PEER_CLOSE_MANAGER_LOG("Nested close: Restart LLGR");
222  close_again_ = true;
223  stats_.nested++;
225  CloseComplete();
226  break;
227 
228  case STALE:
229  case LLGR_STALE:
230  case SWEEP:
231  case DELETE:
232  PEER_CLOSE_MANAGER_LOG("Nested close");
233  close_again_ = true;
234  stats_.nested++;
235  break;
236  }
237 }
238 
240  EnqueueEvent(new Event(EOR_RECEIVED, family));
241 }
242 
244  if ((state_ == GR_TIMER || state_ == LLGR_TIMER) && !families_.empty()) {
245  if (event->family == Address::UNSPEC) {
246  families_.clear();
247  } else {
248  families_.erase(event->family);
249  }
250 
251  // Start the timer if all EORs have been received.
252  if (families_.empty())
254  }
255 }
256 
257 // Process RibIn during peer closure.
259  gr_timer_->Cancel();
260  PEER_CLOSE_MANAGER_LOG("GR Timer started to fire after " << time/1000 <<
261  " seconds");
262  gr_timer_->Start(time,
263  boost::bind(&PeerCloseManager::RestartTimerCallback, this));
264 }
265 
267  CHECK_CONCURRENCY("timer::TimerTask");
269  return false;
270 }
271 
274 
275  PEER_CLOSE_MANAGER_LOG("GR Timer callback started");
276  if (state_ != GR_TIMER && state_ != LLGR_TIMER)
277  return;
278 
279  if (peer_close_->IsReady() && !families_.empty()) {
280  // Fake reception of all EORs.
281  for (IPeerClose::Families::iterator i = families_.begin(), next = i;
282  i != families_.end(); i = next) {
283  next++;
284  PEER_CLOSE_MANAGER_LOG("Simulate EoR reception for family " << *i);
286  }
287  } else {
288  ProcessClosure();
289  }
290 }
291 
292 // Route stale timer callback. If the peer has come back up, sweep routes for
293 // those address families that are still active. Delete the rest
295  // If the peer is back up and this address family is still supported,
296  // sweep old paths which may not have come back in the new session
297  switch (state_) {
298  case NONE:
299  if (!graceful_ || !peer_close_->IsCloseGraceful()) {
301  stats_.deletes++;
302  } else {
304  stats_.stale++;
305  StaleNotify();
306  return;
307  }
308  break;
309  case GR_TIMER:
310  if (peer_close_->IsReady()) {
312  gr_elapsed_ = 0;
313  llgr_elapsed_ = 0;
314  stats_.sweep++;
315  break;
316  }
319  stats_.llgr_stale++;
321  break;
322  }
324  stats_.deletes++;
325  break;
326 
327  case LLGR_TIMER:
328  if (peer_close_->IsReady()) {
330  gr_elapsed_ = 0;
331  llgr_elapsed_ = 0;
332  stats_.sweep++;
333  break;
334  }
336  stats_.deletes++;
337  break;
338 
339  case STALE:
340  case LLGR_STALE:
341  case SWEEP:
342  case DELETE:
343  assert(false);
344  return;
345  }
346 
347  if (state_ == DELETE)
350 }
351 
354  gr_timer_->Cancel();
355  families_.clear();
356  stats_.init++;
357 
358  // Nested closures trigger fresh GR
359  if (close_again_) {
360  close_again_ = false;
361  CloseInternal();
362  }
363 }
364 
366  bool check = (state_ == SWEEP);
367  if (do_assert)
368  assert(check);
369  return check;
370 }
371 
373  bool check = false;
374  check |= (state_ == STALE || state_ == LLGR_STALE || state_ == SWEEP ||
375  state_ == DELETE);
376  check |= (membership_state_ == MEMBERSHIP_IN_USE);
377  check |= (membership_req_pending_ > 0);
378  if (do_assert)
379  assert(check);
380  return check;
381 }
382 
384  bool check = (membership_state_ != MEMBERSHIP_IN_USE);
385  if (do_assert)
386  assert(check);
387  return check;
388 }
389 
391  bool check = !membership_req_pending_;
392  if (do_assert)
393  assert(check);
394  return check;
395 }
396 
399  if (!AssertSweepState())
400  return;
401 
402  // Notify clients to trigger sweep as appropriate.
404 
405  // Reset MembershipUse state after client has been notified above.
407  CloseComplete();
408 }
409 
410 // Notify clients about entering Stale event.
413 
415  if (!AssertMembershipState())
416  return;
417  MembershipRequest(NULL);
418 }
419 
422 }
423 
424 void PeerCloseManager::GetRegisteredRibs(std::list<BgpTable *> *tables) {
426  mgr->GetRegisteredRibs(peer_close_->peer(), tables);
427 }
428 
431  return mgr->IsRegistered(peer_close_->peer(), table);
432 }
433 
436  mgr->Unregister(peer_close_->peer(), table);
437 }
438 
441  mgr->WalkRibIn(peer_close_->peer(), table);
442 }
443 
446  mgr->UnregisterRibOut(peer_close_->peer(), table);
447 }
448 
451  return mgr->IsRibInRegistered(peer_close_->peer(), table);
452 }
453 
456  mgr->UnregisterRibIn(peer_close_->peer(), table);
457 }
458 
460  if (!AssertMembershipState())
461  return;
462 
463  // Pause if membership manager is not ready for usage.
464  if (!CanUseMembershipManager()) {
466  PEER_CLOSE_MANAGER_LOG("Wait for membership manager availability");
467  return;
468  }
471 }
472 
475 
478  return;
480  std::list<BgpTable *> tables;
481  GetRegisteredRibs(&tables);
482 
483  if (tables.empty()) {
484  assert(MembershipRequestCallback(NULL));
485  return;
486  }
487 
488  // Account for extra increment above.
490  BOOST_FOREACH(BgpTable *table, tables) {
492  if (IsRegistered(table)) {
495  "MembershipManager::Unregister");
496  Unregister(table);
497  } else if (state_ == PeerCloseManager::SWEEP) {
498  PEER_CLOSE_MANAGER_TABLE_LOG("MembershipManager::WalkRibIn");
499  WalkRibIn(table);
500  } else {
502  "MembershipManager::UnregisterRibOut");
503  UnregisterRibOut(table);
504  }
505  } else {
506  assert(IsRibInRegistered(table));
509  "MembershipManager::UnregisterRibIn");
510  UnregisterRibIn(table);
511  } else {
512  PEER_CLOSE_MANAGER_TABLE_LOG("MembershipManager::WalkRibIn");
513  WalkRibIn(table);
514  }
515  }
516  }
517 }
518 
521 }
522 
523 // Close process for this peer in terms of walking RibIns and RibOuts are
524 // complete. Do the final cleanups necessary and notify interested party
525 //
526 // Retrun true if we are done using membership manager, false otherwise.
529 
530  bool result = false;
531  PEER_CLOSE_MANAGER_LOG("MembershipRequestCallback");
532 
534  return result;
536  return result;
537 
538  // Indicate to the caller that we are done using the membership manager.
539  result = true;
540 
541  if (state_ == DELETE) {
543  peer_close_->Delete();
544  gr_elapsed_ = 0;
545  llgr_elapsed_ = 0;
546  stats_.init++;
547  close_again_ = false;
548  graceful_ = true;
550  return result;
551  }
552 
553  // Process nested closures.
554  if (close_again_) {
556  CloseComplete();
557 
558  // Nested closure can make membership manager to be in use again.
560  }
561 
562  // If any GR stale timer has to be launched, then to wait for some time
563  // hoping for the peer (and the paths) to come back up.
564  if (state_ == STALE) {
568 
569  // Offset restart time with elapsed time during nested closures.
570  int time = peer_close_->GetGracefulRestartTime() * 1000;
571  time -= gr_elapsed_;
572  if (time < 0)
573  time = 0;
574  StartRestartTimer(time);
575  stats_.gr_timer++;
577  return result;
578  }
579 
580  // From LLGR_STALE state, switch to LLGR_TIMER state. Typically this would
581  // be a very long timer, and we expect to receive EORs before this timer
582  // expires.
583  // Just like for GRSTALE in the above case, before moving to LLGR_TIMER and
584  // starting LLGR_TIMER, we can check if the peer can come back up.
585  if (state_ == LLGR_STALE) {
589 
590  // Offset restart time with elapsed time during nested closures.
591  int time = peer_close_->GetLongLivedGracefulRestartTime() * 1000;
592  time -= llgr_elapsed_;
593  if (time < 0)
594  time = 0;
595  StartRestartTimer(time);
596  stats_.llgr_timer++;
598  return result;
599  }
600 
602  return result;
603 }
604 
605 void PeerCloseManager::FillRouteCloseInfo(PeerCloseInfo *close_info) const {
606  std::map<std::string, PeerCloseRouteInfo> route_stats;
607 
608  for (int i = 0; i < Address::NUM_FAMILIES; i++) {
609  if (!stats_.route_stats[i].IsSet())
610  continue;
611  PeerCloseRouteInfo route_info;
612  route_info.set_staled(stats_.route_stats[i].staled);
613  route_info.set_llgr_staled(stats_.route_stats[i].llgr_staled);
614  route_info.set_refreshed(stats_.route_stats[i].refreshed);
615  route_info.set_fresh(stats_.route_stats[i].fresh);
616  route_info.set_deleted(stats_.route_stats[i].deleted);
617  route_stats[Address::FamilyToString(static_cast<Address::Family>(i))] =
618  route_info;
619  }
620 
621  if (!route_stats.empty())
622  close_info->set_route_stats(route_stats);
623 }
624 
625 BgpNeighborResp *PeerCloseManager::FillCloseInfo(BgpNeighborResp *resp) const {
626  PeerCloseInfo peer_close_info;
627  peer_close_info.set_state(GetStateName(state_));
628  peer_close_info.set_membership_state(
630  peer_close_info.set_close_again(close_again_);
631  peer_close_info.set_graceful(graceful_);
632  peer_close_info.set_init(stats_.init);
633  peer_close_info.set_close(stats_.close);
634  peer_close_info.set_nested(stats_.nested);
635  peer_close_info.set_deletes(stats_.deletes);
636  peer_close_info.set_stale(stats_.stale);
637  peer_close_info.set_llgr_stale(stats_.llgr_stale);
638  peer_close_info.set_sweep(stats_.sweep);
639  peer_close_info.set_gr_timer(stats_.gr_timer);
640  peer_close_info.set_llgr_timer(stats_.llgr_timer);
641  FillRouteCloseInfo(&peer_close_info);
642 
643  resp->set_peer_close_info(peer_close_info);
644 
645  return resp;
646 }
647 
649  const BgpPath *old_path, uint32_t path_flags) const {
650  if (state_ == NONE)
651  return;
652 
653  if (!old_path)
654  stats_.route_stats[family].fresh++;
655  else if (old_path->IsStale() && !(path_flags & BgpPath::Stale))
656  stats_.route_stats[family].refreshed++;
657 }
658 
660  BgpRoute *rt, BgpPath *path) {
661  CHECK_CONCURRENCY("db::DBTable");
663  BgpAttrPtr attrs;
664 
665  BgpTable *table = static_cast<BgpTable *>(root->parent());
666  assert(table);
667 
668  uint32_t stale = 0;
669 
670  switch (state_) {
671  case NONE:
672  case GR_TIMER:
673  case LLGR_TIMER:
674  return false;
675 
676  case SWEEP:
677 
678  // Stale paths must be deleted.
679  if (!path->IsStale() && !path->IsLlgrStale())
680  return false;
681  if (path->IsStale()) {
682  path->ResetStale();
683  table->UpdateStalePathCount(-1);
684  }
685  if (path->IsLlgrStale()) {
686  path->ResetLlgrStale();
687  table->UpdateLlgrStalePathCount(-1);
688  }
690  attrs = NULL;
691  stats_.route_stats[table->family()].deleted++;
692  break;
693 
694  case DELETE:
695 
696  // This path must be deleted. Hence attr is not required.
698  attrs = NULL;
699  stats_.route_stats[table->family()].deleted++;
700  break;
701 
702  case STALE:
703 
704  // We do not support GR for multicast routes (yet).
705  if ((table->family() == Address::ERMVPN) ||
706  (table->family() == Address::MVPN)) {
708  attrs = NULL;
709  stats_.route_stats[table->family()].deleted++;
710  break;
711  }
712 
713  // If path is already marked as stale, then there is no need to
714  // process again. This can happen if the session flips while in
715  // GR_TIMER state.
716  if (path->IsStale())
717  return false;
718 
719  // This path must be marked for staling. Update the local
720  // preference and update the route accordingly.
722  attrs = path->GetAttr();
723  stale = BgpPath::Stale;
724  stats_.route_stats[table->family()].staled++;
725  break;
726 
727  case LLGR_STALE:
728 
729  // If the path has NO_LLGR community, DELETE it.
730  if (path->GetAttr()->community() &&
731  path->GetAttr()->community()->ContainsValue(
734  attrs = NULL;
735  stats_.route_stats[table->family()].deleted++;
736  break;
737  }
738 
739  // If path is already marked as llgr_stale, then there is no
740  // need to process again. This can happen if the session flips
741  // while in LLGR_TIMER state.
742  if (path->IsLlgrStale())
743  return false;
744 
745  attrs = path->GetAttr();
746  stale = BgpPath::LlgrStale;
748  stats_.route_stats[table->family()].llgr_staled++;
749  break;
750  }
751 
752  // Feed the route modify/delete request to the table input process.
753  return table->InputCommon(root, rt, path, peer_close_->peer(), NULL, oper,
754  attrs, path->GetPathId(), path->GetFlags() | stale, path->GetLabel(),
755  path->GetL3Label());
756 }
757 
758 //
759 // Handler for an Event.
760 //
763  bool result;
764 
765  switch (event->event_type) {
766  case EVENT_NONE:
767  break;
768  case CLOSE:
769  Close(event);
770  break;
771  case EOR_RECEIVED:
773  break;
774  case MEMBERSHIP_REQUEST:
775  MembershipRequest(event);
776  break;
778  result = MembershipRequestCallback(event);
779 
780  // Notify clients if we are no longer using the membership mgr.
781  if (result)
783  break;
784  case TIMER_CALLBACK:
785  RestartTimerCallback(event);
786  break;
787  }
788 
789  delete event;
790  return true;
791 }
virtual void UnregisterRibOut(IPeer *peer, BgpTable *table)
const Community * community() const
Definition: bgp_attr.h:914
IPeerClose * peer_close_
virtual bool IsRegistered(BgpTable *table) const
tbb::atomic< int > membership_req_pending_
void set_membership_state(MembershipState state)
MembershipState membership_state_
virtual bool IsCloseLongLivedGraceful() const =0
The TaskScheduler keeps track of what tasks are currently schedulable. When a task is enqueued it is ...
Definition: task.h:178
virtual int GetLongLivedGracefulRestartTime() const =0
std::string GetEventName(EventType eventType) const
virtual bool IsCloseGraceful() const =0
virtual void StartRestartTimer(int time)
void ResetLlgrStale()
Definition: bgp_path.h:133
virtual void ReceiveEndOfRIB(Address::Family family)=0
Family
Definition: address.h:24
bool IsStale() const
Definition: bgp_path.h:107
bool IsRegistered(const IPeer *peer, const BgpTable *table) const
#define PEER_CLOSE_MANAGER_LOG(msg)
const uint32_t GetPathId() const
Definition: bgp_path.h:78
DBTableBase * parent()
virtual void WalkRibIn(BgpTable *table)
virtual bool CanUseMembershipManager() const
virtual Address::Family family() const =0
uint32_t GetFlags() const
Definition: bgp_path.h:100
#define MOVE_TO_STATE(state)
void ProcessEORMarkerReceived(Address::Family family)
#define PEER_CLOSE_MANAGER_TABLE_LOG(msg)
void EnqueueEvent(Event *event)
void ResetStale()
Definition: bgp_path.h:126
PeerCloseManager(IPeerClose *peer_close, boost::asio::io_context *io_service)
uint32_t GetL3Label() const
Definition: bgp_path.h:90
void WalkRibIn(IPeer *peer, BgpTable *table)
boost::intrusive_ptr< const BgpAttr > BgpAttrPtr
Definition: bgp_attr.h:991
virtual void Unregister(BgpTable *table)
virtual bool AssertMembershipReqCount(bool do_assert=true)
Event
Definition: http_client.h:27
virtual bool AssertSweepState(bool do_assert=true)
std::string GetMembershipStateName(MembershipState state) const
bool ContainsValue(uint32_t value) const
Definition: community.cc:113
virtual void CloseComplete()=0
#define CHECK_CONCURRENCY(...)
virtual void Unregister(IPeer *peer, BgpTable *table)
RouteStats route_stats[Address::NUM_FAMILIES]
virtual void GracefulRestartStale()=0
void UpdateStalePathCount(int count)
Definition: bgp_table.h:172
void UpdateRouteStats(Address::Family family, const BgpPath *old_path, uint32_t path_flags) const
virtual void CustomClose()=0
void UnregisterRibIn(IPeer *peer, BgpTable *table)
virtual int GetGracefulRestartTime() const =0
virtual void LongLivedGracefulRestartStale()=0
uint32_t GetLabel() const
Definition: bgp_path.h:89
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:201
bool EventCallback(Event *event)
bool Cancel()
Definition: timer.cc:150
virtual BgpServer * server()=0
virtual void UnregisterRibIn(BgpTable *table)
static std::string FamilyToString(Family fmly)
Definition: address.cc:63
boost::asio::io_context * ioservice()
Definition: bgp_server.cc:682
virtual void MembershipRequestCallbackComplete()=0
virtual void GracefulRestartSweep()=0
void UpdateLlgrStalePathCount(int count)
Definition: bgp_table.h:173
virtual bool IsRibInRegistered(BgpTable *table) const
virtual void GetRegisteredRibs(std::list< BgpTable * > *tables)
bool IsLlgrStale() const
Definition: bgp_path.h:110
void Close(bool graceful)
const BgpAttr * GetAttr() const
Definition: bgp_path.h:87
virtual void GetLongLivedGracefulRestartFamilies(Families *) const =0
bool InputCommon(DBTablePartBase *root, BgpRoute *rt, BgpPath *path, const IPeer *peer, DBRequest *req, DBRequest::DBOperation oper, BgpAttrPtr attrs, uint32_t path_id, uint32_t flags, uint32_t label, uint32_t l3_label)
Definition: bgp_table.cc:836
bool Start(int time, Handler handler, ErrorHandler error_handler=NULL)
Definition: timer.cc:108
bool IsRibInRegistered(const IPeer *peer, const BgpTable *table) const
virtual bool IsReady() const =0
void FillRouteCloseInfo(PeerCloseInfo *close_info) const
bool MembershipPathCallback(DBTablePartBase *root, BgpRoute *rt, BgpPath *path)
virtual IPeer * peer() const =0
virtual bool AssertMembershipManagerInUse(bool do_assert=true)
BgpMembershipManager * membership_mgr()
Definition: bgp_server.h:173
std::string GetStateName(State state) const
virtual void Delete()=0
virtual void UnregisterRibOut(BgpTable *table)
BgpNeighborResp * FillCloseInfo(BgpNeighborResp *resp) const
virtual void GetGracefulRestartFamilies(Families *) const =0
virtual bool AssertMembershipState(bool do_assert=true)
int64_t GetElapsedTime() const
Definition: timer.cc:235
void GetRegisteredRibs(const IPeer *peer, std::list< BgpTable * > *table_list) const
virtual const char * GetTaskName() const =0
IPeerClose::Families families_
boost::scoped_ptr< WorkQueue< Event * > > event_queue_
virtual bool CanUseMembershipManager() const =0
static bool DeleteTimer(Timer *Timer)
Definition: timer.cc:222