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_RIBOUT_UPDATES_H_ 7 : #define SRC_BGP_BGP_RIBOUT_UPDATES_H_ 8 : 9 : #include <boost/scoped_ptr.hpp> 10 : 11 : #include <vector> 12 : 13 : #include "base/util.h" 14 : 15 : class BgpTable; 16 : class DBEntryBase; 17 : class IPeerUpdate; 18 : class Message; 19 : class RibPeerSet; 20 : class RibUpdateMonitor; 21 : class RibOut; 22 : class RouteUpdate; 23 : class RouteUpdatePtr; 24 : class ShowRibOutStatistics; 25 : class UpdateQueue; 26 : struct UpdateInfo; 27 : struct UpdateMarker; 28 : 29 : // 30 : // This class is a logical abstraction of the update processing state and 31 : // functionality for a RibOut. An instance of RibOutUpdates is created per 32 : // DB partition. So there's a 1:N mapping between RibOut and RibOutUpdates. 33 : // Further, the RibOutUpdates keeps a smart pointer to a RibUpdateMonitor 34 : // with which it has a 1:1 association. 35 : // 36 : // A RibOutUpdates also maintains a vector of pointers to UpdateQueue. The 37 : // 2 UpdateQueues are used for bulk and regular updates. Note that access 38 : // to all the UpdateQueue goes through the RibUpdateMonitor which enforces 39 : // all the concurrency constraints. There's an exception for UpdateMarkers 40 : // which are accessed directly through the UpdateQueue. 41 : // 42 : class RibOutUpdates { 43 : public: 44 : typedef std::vector<UpdateQueue *> QueueVec; 45 : static const int kQueueIdInvalid = -1; 46 : enum QueueId { 47 : QFIRST = 0, 48 : QBULK = 0, 49 : QUPDATE, 50 : QCOUNT 51 : }; 52 : 53 : struct Stats { 54 : uint64_t messages_built_count_; 55 : uint64_t messages_sent_count_; 56 : uint64_t reach_count_; 57 : uint64_t unreach_count_; 58 : uint64_t tail_dequeue_count_; 59 : uint64_t peer_dequeue_count_; 60 : uint64_t marker_split_count_; 61 : uint64_t marker_merge_count_; 62 : uint64_t marker_move_count_; 63 : }; 64 : 65 : RibOutUpdates(RibOut *ribout, int index); 66 : virtual ~RibOutUpdates(); 67 : 68 : static void Initialize(); 69 : static void Terminate(); 70 : 71 : void Enqueue(DBEntryBase *db_entry, RouteUpdate *rt_update); 72 : 73 : virtual bool TailDequeue(int queue_id, const RibPeerSet &msync, 74 : RibPeerSet *blocked, RibPeerSet *unsync); 75 : virtual bool PeerDequeue(int queue_id, IPeerUpdate *peer, 76 : RibPeerSet *blocked); 77 : 78 : // Enqueue a marker at the head of the queue with this bit set. 79 : bool QueueJoin(int queue_id, int bit); 80 : void QueueLeave(int queue_id, int bit); 81 : 82 : bool Empty() const; 83 : size_t queue_size(int queue_id) const; 84 : size_t queue_marker_count(int queue_id) const; 85 : 86 2380097 : RibUpdateMonitor *monitor() { return monitor_.get(); } 87 : 88 600 : UpdateQueue *queue(int queue_id) { 89 600 : return queue_vec_[queue_id]; 90 : } 91 : 92 : QueueVec &queue_vec() { return queue_vec_; } 93 : const QueueVec &queue_vec() const { return queue_vec_; } 94 : 95 : void AddStatisticsInfo(int queue_id, Stats *stats) const; 96 : 97 : private: 98 : friend class RibOutUpdatesTest; 99 : friend class XmppMessageBuilderTest; 100 : friend class XmppMvpnMessageBuilderTest; 101 : 102 : Message *GetMessage() const; 103 : bool DequeueCommon(UpdateQueue *queue, UpdateMarker *marker, 104 : RouteUpdate *rt_update, RibPeerSet *blocked); 105 : 106 : // Add additional updates. 107 : void UpdatePack(int queue_id, Message *message, UpdateInfo *start_uinfo, 108 : const RibPeerSet &isect); 109 : 110 : // Transmit the updates to a set of peers. 111 : void UpdateSend(int queue_id, Message *message, const RibPeerSet &dst, 112 : RibPeerSet *blocked); 113 : void UpdateFlush(const RibPeerSet &dst, RibPeerSet *blocked); 114 : 115 : // Remove the advertised bits on an update. This updates the history 116 : // information. Returns true if the UpdateInfo should be deleted. 117 : bool ClearAdvertisedBits(RouteUpdate *rt_update, UpdateInfo *uinfo, 118 : const RibPeerSet &bits, bool update_history); 119 : 120 : void StoreHistory(RouteUpdate *rt_update); 121 : void ClearState(RouteUpdate *rt_update); 122 : void ClearUpdate(RouteUpdatePtr *update); 123 : 124 : bool UpdateMarkersOnBlocked(UpdateMarker *marker, RouteUpdate *rt_update, 125 : const RibPeerSet *blocked); 126 : 127 : RibOut *ribout_; 128 : int index_; 129 : QueueVec queue_vec_; 130 : Stats stats_[QCOUNT]; 131 : boost::scoped_ptr<RibUpdateMonitor> monitor_; 132 : static std::vector<Message *> bgp_messages_; 133 : static std::vector<Message *> xmpp_messages_; 134 : 135 : DISALLOW_COPY_AND_ASSIGN(RibOutUpdates); 136 : }; 137 : 138 : #endif // SRC_BGP_BGP_RIBOUT_UPDATES_H_