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

Generated by: LCOV version 1.14