LCOV - code coverage report
Current view: top level - bgp - bgp_update_monitor.h (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 32 32 100.0 %
Date: 2026-06-08 02:02:55 Functions: 11 11 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
       3             :  */
       4             : 
       5             : #ifndef SRC_BGP_BGP_UPDATE_MONITOR_H_
       6             : #define SRC_BGP_BGP_UPDATE_MONITOR_H_
       7             : 
       8             : #include <boost/function.hpp>
       9             : 
      10             : #include <algorithm>
      11             : #include <vector>
      12             : 
      13             : #include "base/util.h"
      14             : 
      15             : class AdvertiseSList;
      16             : class DBEntryBase;
      17             : struct DBState;
      18             : class RibOut;
      19             : class RibPeerSet;
      20             : class RouteState;
      21             : class RouteUpdate;
      22             : class UpdateEntry;
      23             : class UpdateInfo;
      24             : class UpdateInfoSList;
      25             : class UpdateList;
      26             : class UpdateQueue;
      27             : 
      28             : //
      29             : // This class implements an encapsulator for a RouteUpdate which grants the
      30             : // user the right to modify the update without holding a lock on the monitor.
      31             : // The user must go through the RouteUpdateMonitor and the UpdateQueue to
      32             : // remove the RouteUpdate from the UpdateQueue.
      33             : //
      34             : // A RouteUpdatePtr with a NULL RouteUpdate indicates either the end of an
      35             : // UpdateQueue or the presence of an UpdateMarker.
      36             : //
      37             : // A RouteUpdatePtr is typically used by bgp::SendUpdate task that's dequeuing
      38             : // updates from the UpdateQueue.
      39             : //
      40             : // Movable semantics implemented in c++03.
      41             : //
      42             : class RouteUpdatePtr {
      43             : public:
      44             :     struct Proxy {
      45      937343 :         Proxy() : rt_update(NULL) {
      46      937343 :         }
      47             :         RouteUpdate *rt_update;
      48             :     };
      49     2136593 :     RouteUpdatePtr() : rt_update_(NULL) {
      50     2136593 :     }
      51             :     RouteUpdatePtr(RouteUpdate *rt_update);
      52         419 :     RouteUpdatePtr(RouteUpdatePtr &rhs) : rt_update_(NULL) {
      53         419 :         swap(rhs);
      54         419 :     }
      55      937294 :     RouteUpdatePtr(Proxy rhs) : rt_update_(rhs.rt_update) {
      56      937294 :     }
      57             :     ~RouteUpdatePtr();
      58             : 
      59     1244887 :     RouteUpdate *operator->() { return rt_update_; }
      60     5240430 :     RouteUpdate *get() { return rt_update_; }
      61             : 
      62      937000 :     RouteUpdatePtr &operator=(RouteUpdatePtr &rhs) {
      63      937000 :         swap(rhs);
      64      936985 :         return *this;
      65             :     }
      66             : 
      67      937185 :     RouteUpdatePtr &operator=(Proxy rhs) {
      68      937185 :         RouteUpdatePtr tmp(rhs);
      69      937297 :         swap(tmp);
      70     1874565 :         return *this;
      71      937287 :     }
      72             : 
      73      918246 :     RouteUpdate *release() {
      74      918246 :         RouteUpdate *rt_update = rt_update_;
      75      918246 :         RouteUpdatePtr tmp;
      76      918244 :         tmp.swap(*this);
      77     1836432 :         return rt_update;
      78      918222 :     }
      79             : 
      80     2792668 :     void swap(RouteUpdatePtr &rhs) {
      81     2792668 :         std::swap(rt_update_, rhs.rt_update_);
      82     2792522 :     }
      83             : 
      84      937326 :     operator Proxy() {
      85      937326 :         Proxy proxy;
      86      937331 :         std::swap(proxy.rt_update, rt_update_);
      87      937307 :         return proxy;
      88             :     }
      89             : 
      90             : private:
      91             :     RouteUpdate *rt_update_;
      92             : };
      93             : 
      94             : //
      95             : // This implements the interface between the export module which generates
      96             : // updates (using the db::DBTable Task) and the update sender module which
      97             : // consumes them (using the bgp::SendUpdate Task).  Both export processing
      98             : // and update sender run concurrently under multiple table shards.
      99             : // TaskPolicy configuration ensures that they don't run in parallel for the
     100             : // same same shard.
     101             : //
     102             : class RibUpdateMonitor {
     103             : public:
     104             :     typedef boost::function<bool(const RouteUpdate *)> UpdateCmp;
     105             :     typedef std::vector<UpdateQueue *> QueueVec;
     106             : 
     107             :     explicit RibUpdateMonitor(RibOut *ribout, QueueVec *queue_vec);
     108             : 
     109             :     // Used by export module to obtain exclusive access to the DB state.
     110             :     // If an update is currently present and the comparison function
     111             :     // returns true, it is considered a duplicate and the function returns
     112             :     // NULL. Otherwise the update is dequeued and returned.
     113             :     DBState *GetDBStateAndDequeue(DBEntryBase *db_entry,
     114             :                                   UpdateCmp cmp,
     115             :                                   bool *duplicate);
     116             : 
     117             :     // Fill the mcurrent and mscheduled parameters with the contents of the
     118             :     // advertised bitmask (history) plus and updates that may be enqueue in
     119             :     // the specified queue.  Returns true if there is an update currently
     120             :     // enqueued. False otherwise.
     121             :     bool GetPeerSetCurrentAndScheduled(DBEntryBase *db_entry,
     122             :                                        int queue_id,
     123             :                                        RibPeerSet *mcurrent,
     124             :                                        RibPeerSet *mscheduled);
     125             : 
     126             :     // Used by the export module to enqueue/dequeue updates.
     127             :     bool EnqueueUpdate(DBEntryBase *db_entry,
     128             :                        RouteUpdate *rt_update,
     129             :                        UpdateList *uplist = NULL);
     130             :     void DequeueUpdate(RouteUpdate *rt_update);
     131             : 
     132             : 
     133             :     // Merge this new update into the existing state.
     134             :     bool MergeUpdate(DBEntryBase *db_entry, RouteUpdate *rt_update);
     135             : 
     136             :     // Cancel scheduled updates for the route and/or remove any current
     137             :     // advertised state.
     138             :     void ClearPeerSetCurrentAndScheduled(DBEntryBase *db_entry,
     139             :                                          const RibPeerSet &mleave);
     140             : 
     141             :     // Used by the update dequeue process to retrieve an update.
     142             :     RouteUpdatePtr GetNextUpdate(int queue_id, UpdateEntry *upentry);
     143             : 
     144             :     // Used by the update dequeue process to retrieve the next entry in the
     145             :     // queue. If this is an update, it returns the pointer.
     146             :     RouteUpdatePtr GetNextEntry(int queue_id, UpdateEntry *upentry,
     147             :                                 UpdateEntry **next_upentry_p);
     148             : 
     149             :     // Used when iterating through updates with the same attribute.
     150             :     RouteUpdatePtr GetAttrNext(int queue_id, UpdateInfo *current_uinfo,
     151             :                                UpdateInfo **next_uinfo_p);
     152             : 
     153             :     void SetEntryState(DBEntryBase *db_entry, DBState *dbstate);
     154             :     void ClearEntryState(DBEntryBase *db_entry);
     155             : 
     156             : private:
     157             :     // Helper functions for GetRouteStateAndDequeue
     158             :     DBState *GetRouteUpdateAndDequeue(DBEntryBase *db_entry,
     159             :                                       RouteUpdate *rt_update,
     160             :                                       UpdateCmp cmp, bool *duplicate);
     161             :     DBState *GetUpdateListAndDequeue(DBEntryBase *db_entry,
     162             :                                      UpdateList *uplist);
     163             : 
     164             :     // Helper functions for MergeUpdate
     165             :     bool RouteStateMergeUpdate(DBEntryBase *db_entry,
     166             :                                RouteUpdate *rt_update,
     167             :                                RouteState *rstate);
     168             :     bool RouteUpdateMergeUpdate(DBEntryBase *db_entry,
     169             :                                 RouteUpdate *rt_update,
     170             :                                 RouteUpdate *current_rt_update);
     171             :     bool UpdateListMergeUpdate(DBEntryBase *db_entry,
     172             :                                RouteUpdate *rt_update,
     173             :                                UpdateList *uplist);
     174             : 
     175             :     // Helper functions for ClearPeerSetCurrentAndScheduled
     176             :     void AdvertiseSListClearBits(AdvertiseSList &adv_slist,
     177             :             const RibPeerSet &clear);
     178             :     void UpdateInfoSListClearBits(UpdateInfoSList &uinfo_slist,
     179             :             const RibPeerSet &clear);
     180             :     void RouteStateClearPeerSet(DBEntryBase *db_entry,
     181             :             RouteState *rstate, const RibPeerSet &mleave);
     182             :     bool RouteUpdateClearPeerSet(DBEntryBase *db_entry,
     183             :             RouteUpdate *rt_update, const RibPeerSet &mleave);
     184             :     bool UpdateListClearPeerSet(DBEntryBase *db_entry,
     185             :             UpdateList *uplist, const RibPeerSet &mleave);
     186             : 
     187             :     RibOut *ribout_;
     188             :     QueueVec *queue_vec_;
     189             : 
     190             :     DISALLOW_COPY_AND_ASSIGN(RibUpdateMonitor);
     191             : };
     192             : 
     193             : #endif  // SRC_BGP_BGP_UPDATE_MONITOR_H_

Generated by: LCOV version 1.14