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