LCOV - code coverage report
Current view: top level - bgp - peer_close_manager.h (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 60 60 100.0 %
Date: 2026-11-09 02:10:49 Functions: 22 22 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
       3             :  * Copyright Contributors to the OpenSDN project
       4             :  */
       5             : 
       6             : #ifndef SRC_BGP_PEER_CLOSE_MANAGER_H_
       7             : #define SRC_BGP_PEER_CLOSE_MANAGER_H_
       8             : 
       9             : #include <list>
      10             : #include <string>
      11             : #include <atomic>
      12             : 
      13             : #include "base/timer.h"
      14             : #include "base/util.h"
      15             : #include "base/queue_task.h"
      16             : #include "db/db_table_walker.h"
      17             : #include "bgp/ipeer.h"
      18             : 
      19             : class BgpMembershipManager;
      20             : class BgpNeighborResp;
      21             : class BgpRoute;
      22             : class BgpTable;
      23             : class PeerCloseInfo;
      24             : 
      25             : // PeerCloseManager
      26             : //
      27             : // Manager close process of an IPeer (And hence should support both BgpPeers
      28             : // and XmppPeers)
      29             : //
      30             : // Among other things, RibIns and RibOuts of peers must be closed/deleted
      31             : // completely before a peer can be completely closed/deleted. This class
      32             : // provides this capability.
      33             : //
      34             : // RibIn and RibOut close are handled by invoking Unregister request with
      35             : // BgpMembershipManager class.
      36             : //
      37             : // Once RibIns and RibOuts are processed, notification callback function is
      38             : // invoked to signal the completion of close process
      39             : //
      40             : class PeerCloseManager {
      41             : public:
      42             :     PeerCloseManager(IPeerClose *peer_close,
      43             :                      boost::asio::io_context *io_service);
      44             :     explicit PeerCloseManager(IPeerClose *peer_close);
      45             :     virtual ~PeerCloseManager();
      46             : 
      47      302144 :     bool IsMembershipInUse() const {
      48      302144 :         return membership_state_ == MEMBERSHIP_IN_USE;
      49             :     }
      50       99700 :     bool IsMembershipInWait() const {
      51       99700 :         return membership_state_ == MEMBERSHIP_IN_WAIT;
      52             :     }
      53          84 :     IPeerClose *peer_close() const { return peer_close_; }
      54        2304 :     IPeerClose::Families *families() { return &families_; }
      55             : 
      56       51723 :     bool IsCloseInProgress() const { return state_ != NONE; }
      57       14983 :     bool IsInDeleteState() const { return state_ == DELETE; }
      58        9424 :     bool IsInGRTimerWaitState() const {
      59        9424 :         return state_ == GR_TIMER || state_ == LLGR_TIMER;
      60             :     }
      61         636 :     bool IsInLlgrTimerWaitState() const { return state_ == LLGR_TIMER; }
      62       23802 :     bool IsQueueEmpty() const { return event_queue_->IsQueueEmpty(); }
      63             : 
      64             :     void Close(bool graceful);
      65             :     void ProcessEORMarkerReceived(Address::Family family);
      66             :     void MembershipRequest();
      67             :     void MembershipRequestCallback();
      68             :     BgpNeighborResp *FillCloseInfo(BgpNeighborResp *resp) const;
      69             :     bool MembershipPathCallback(DBTablePartBase *root, BgpRoute *rt,
      70             :                                 BgpPath *path);
      71             :     void UpdateRouteStats(Address::Family family, const BgpPath *old_path,
      72             :                           uint32_t path_flags) const;
      73             : 
      74             : private:
      75             :     friend class BgpServerUnitTest;
      76             :     friend class PeerCloseTest;
      77             :     friend class PeerCloseManagerTest;
      78             :     friend class GracefulRestartTest;
      79             : 
      80             :     enum State {
      81             :         BEGIN_STATE,
      82             :         NONE = BEGIN_STATE,
      83             :         STALE,
      84             :         GR_TIMER,
      85             :         LLGR_STALE,
      86             :         LLGR_TIMER,
      87             :         SWEEP,
      88             :         DELETE,
      89             :         END_STATE = DELETE
      90             :     };
      91             : 
      92             :     enum MembershipState {
      93             :         BEGIN_MEMBERSHIP_STATE,
      94             :         MEMBERSHIP_NONE = BEGIN_MEMBERSHIP_STATE,
      95             :         MEMBERSHIP_IN_USE,
      96             :         MEMBERSHIP_IN_WAIT,
      97             :         END_MEMBERSHIP_STATE = MEMBERSHIP_IN_WAIT
      98             :     };
      99             : 
     100             :     enum EventType {
     101             :         BEGIN_EVENT,
     102             :         EVENT_NONE = BEGIN_EVENT,
     103             :         CLOSE,
     104             :         EOR_RECEIVED,
     105             :         MEMBERSHIP_REQUEST,
     106             :         MEMBERSHIP_REQUEST_COMPLETE_CALLBACK,
     107             :         TIMER_CALLBACK,
     108             :         END_EVENT = TIMER_CALLBACK
     109             :     };
     110             : 
     111             :     struct Event {
     112       20978 :         Event(EventType event_type, bool graceful) :
     113       20978 :                 event_type(event_type), graceful(graceful),
     114       20978 :                 family(Address::UNSPEC) { }
     115       14977 :         Event(EventType event_type, Address::Family family) :
     116       14977 :                 event_type(event_type), graceful(true),
     117       14977 :                 family(family) { }
     118      107503 :         explicit Event(EventType event_type) : event_type(event_type),
     119      107503 :                                                graceful(true),
     120      107503 :                                                family(Address::UNSPEC) { }
     121             :         Event() : event_type(EVENT_NONE), graceful(true),
     122             :                              family(Address::UNSPEC) { }
     123             : 
     124             :         EventType event_type;
     125             :         bool graceful;
     126             :         Address::Family family;
     127             :     };
     128             : 
     129             :     struct Stats {
     130       28561 :         Stats():
     131       28561 :             init(0),
     132       28561 :             close(0),
     133       28561 :             nested(0),
     134       28561 :             deletes(0),
     135       28561 :             stale(0),
     136       28561 :             llgr_stale(0),
     137       28561 :             sweep(0),
     138       28561 :             gr_timer(0),
     139      314169 :             llgr_timer(0) {
     140       28561 :         }
     141             : 
     142             :         struct RouteStats {
     143      285608 :             RouteStats() { reset(); }
     144      642510 :             bool IsSet() const {
     145      642510 :                 return staled || llgr_staled || refreshed || fresh || deleted;
     146             :             }
     147             : 
     148       30720 :             RouteStats& operator=(const RouteStats& other) {
     149       30720 :                 if (this != &other) {
     150       30720 :                     staled.store(other.staled);
     151       30720 :                     llgr_staled.store(other.llgr_staled);
     152       30720 :                     refreshed.store(other.refreshed);
     153       30720 :                     fresh.store(other.fresh);
     154       30720 :                     deleted.store(other.deleted);
     155             :                 }
     156       30720 :                 return *this;
     157             :             }
     158             : 
     159      485068 :             void reset() {
     160      485068 :                 staled = 0;
     161      485070 :                 llgr_staled = 0;
     162      485069 :                 refreshed = 0;
     163      485070 :                 fresh = 0;
     164      485069 :                 deleted = 0;
     165      485069 :             }
     166             : 
     167             :             std::atomic<uint64_t> staled;
     168             :             std::atomic<uint64_t> llgr_staled;
     169             :             std::atomic<uint64_t> refreshed;
     170             :             std::atomic<uint64_t> fresh;
     171             :             std::atomic<uint64_t> deleted;
     172             :         };
     173             : 
     174       19946 :         void ResetRouteStats() {
     175      219406 :             for (size_t i = 0; i < Address::NUM_FAMILIES; i++) {
     176      199460 :                 route_stats[i].reset();
     177             :             }
     178       19946 :         }
     179             : 
     180             :         uint64_t init;
     181             :         uint64_t close;
     182             :         uint64_t nested;
     183             :         uint64_t deletes;
     184             :         uint64_t stale;
     185             :         uint64_t llgr_stale;
     186             :         uint64_t sweep;
     187             :         uint64_t gr_timer;
     188             :         uint64_t llgr_timer;
     189             :         mutable RouteStats route_stats[Address::NUM_FAMILIES];
     190             :     };
     191             : 
     192       10400 :     State state() const { return state_; }
     193        3427 :     const Stats &stats() const { return stats_; }
     194             :     void Close(Event *event);
     195             :     void ProcessEORMarkerReceived(Event *event);
     196             :     virtual void StartRestartTimer(int time);
     197             :     bool RestartTimerCallback();
     198             :     void RestartTimerCallback(Event *event);
     199             :     void ProcessClosure();
     200             :     void CloseComplete();
     201             :     void TriggerSweepStateActions();
     202             :     std::string GetStateName(State state) const;
     203             :     std::string GetMembershipStateName(MembershipState state) const;
     204             :     void FillRouteCloseInfo(PeerCloseInfo *close_info) const;
     205             :     void CloseInternal();
     206             :     void MembershipRequest(Event *event);
     207             :     bool MembershipRequestCallback(Event *event);
     208             :     void StaleNotify();
     209             :     bool EventCallback(Event *event);
     210             :     std::string GetEventName(EventType eventType) const;
     211             :     void EnqueueEvent(Event *event);
     212        1531 :     bool close_again() const { return close_again_; }
     213             :     virtual bool AssertMembershipState(bool do_assert = true);
     214             :     virtual bool AssertMembershipReqCount(bool do_assert = true);
     215             :     virtual bool AssertSweepState(bool do_assert = true);
     216             :     virtual bool AssertMembershipManagerInUse(bool do_assert = true);
     217       64530 :     void set_membership_state(MembershipState state) {
     218       64530 :         membership_state_ = state;
     219       64530 :     }
     220             : 
     221             :     virtual bool CanUseMembershipManager() const;
     222             :     virtual void GetRegisteredRibs(std::list<BgpTable *> *tables);
     223             :     virtual bool IsRegistered(BgpTable *table) const;
     224             :     virtual void Unregister(BgpTable *table);
     225             :     virtual void WalkRibIn(BgpTable *table);
     226             :     virtual void UnregisterRibOut(BgpTable *table);
     227             :     virtual bool IsRibInRegistered(BgpTable *table) const;
     228             :     virtual void UnregisterRibIn(BgpTable *table);
     229             : 
     230             :     IPeerClose *peer_close_;
     231             :     Timer *gr_timer_;
     232             :     boost::scoped_ptr<WorkQueue<Event *> > event_queue_;
     233             :     State state_;
     234             :     bool close_again_;
     235             :     bool graceful_;
     236             :     int gr_elapsed_;
     237             :     int llgr_elapsed_;
     238             :     MembershipState membership_state_;
     239             :     IPeerClose::Families families_;
     240             :     Stats stats_;
     241             :     std::atomic<int> membership_req_pending_;
     242             : };
     243             : 
     244             : #endif  // SRC_BGP_PEER_CLOSE_MANAGER_H_

Generated by: LCOV version 1.14