/
bgp_ribout_updates.h
113 lines (89 loc) · 3.5 KB
/
bgp_ribout_updates.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/*
* Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
*/
#ifndef SRC_BGP_BGP_RIBOUT_UPDATES_H_
#define SRC_BGP_BGP_RIBOUT_UPDATES_H_
#include <boost/scoped_ptr.hpp>
#include <vector>
#include "base/util.h"
class BgpTable;
class DBEntryBase;
class IPeerUpdate;
class Message;
class MessageBuilder;
class RibPeerSet;
class RibUpdateMonitor;
class RibOut;
class RouteUpdate;
class RouteUpdatePtr;
class UpdateQueue;
struct UpdateInfo;
struct UpdateMarker;
//
// This class is a logical abstraction of the update processing state and
// functionality that would have otherwise been part of RibOut itself. As
// such, there's a 1:1 association between a RibOut and a RibOutUpdates.
// Further, the RibOutUpdates keeps a smart pointer to a RibUpdateMonitor
// with which it also has a 1:1 association.
//
// A RibOutUpdates also maintains a vector of pointers to UpdateQueue. The
// 2 UpdateQueues are used for bulk and regular updates. Note that access
// to all the UpdateQueue goes through the RibUpdateMonitor which enforces
// all the concurrency constraints. There's an exception for UpdateMarker
// which are accessed directly through the UpdateQueue.
//
class RibOutUpdates {
public:
typedef std::vector<UpdateQueue *> QueueVec;
static const int kQueueIdInvalid = -1;
enum QueueId {
QFIRST = 0,
QBULK = 0,
QUPDATE,
QCOUNT
};
explicit RibOutUpdates(RibOut *ribout);
virtual ~RibOutUpdates();
void Enqueue(DBEntryBase *db_entry, RouteUpdate *rt_update);
virtual bool TailDequeue(int queue_id,
const RibPeerSet &msync, RibPeerSet *blocked);
virtual bool PeerDequeue(int queue_id, IPeerUpdate *peer,
const RibPeerSet &mready, RibPeerSet *blocked);
// Enqueue a marker at the head of the queue with this bit set.
bool QueueJoin(int queue_id, int bit);
void QueueLeave(int queue_id, int bit);
bool Empty() const;
RibUpdateMonitor *monitor() { return monitor_.get(); }
UpdateQueue *queue(int queue_id) {
return queue_vec_[queue_id];
}
QueueVec &queue_vec() { return queue_vec_; }
const QueueVec &queue_vec() const { return queue_vec_; }
// Testing only
void SetMessageBuilder(MessageBuilder *builder) { builder_ = builder; }
private:
friend class RibOutUpdatesTest;
bool DequeueCommon(UpdateMarker *marker, RouteUpdate *rt_update,
RibPeerSet *blocked);
// Add additional updates.
void UpdatePack(int queue_id, Message *message, UpdateInfo *start_uinfo,
const RibPeerSet &isect);
// Transmit the updates to a set of peers.
void UpdateSend(Message *message, const RibPeerSet &dst,
RibPeerSet *blocked);
// Remove the advertised bits on an update. This updates the history
// information. Returns true if the UpdateInfo should be deleted.
bool ClearAdvertisedBits(RouteUpdate *rt_update, UpdateInfo *uinfo,
const RibPeerSet &bits, bool update_history);
void StoreHistory(RouteUpdate *rt_update);
void ClearState(RouteUpdate *rt_update);
void ClearUpdate(RouteUpdatePtr *update);
bool UpdateMarkersOnBlocked(UpdateMarker *marker, RouteUpdate *rt_update,
const RibPeerSet *blocked);
RibOut *ribout_;
MessageBuilder *builder_;
QueueVec queue_vec_;
boost::scoped_ptr<RibUpdateMonitor> monitor_;
DISALLOW_COPY_AND_ASSIGN(RibOutUpdates);
};
#endif // SRC_BGP_BGP_RIBOUT_UPDATES_H_