OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
bgp_update_monitor.h
Go to the documentation of this file.
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 //
43 public:
44  struct Proxy {
45  Proxy() : rt_update(NULL) {
46  }
48  };
50  }
51  RouteUpdatePtr(RouteUpdate *rt_update);
53  swap(rhs);
54  }
55  RouteUpdatePtr(Proxy rhs) : rt_update_(rhs.rt_update) {
56  }
58 
60  RouteUpdate *get() { return rt_update_; }
61 
63  swap(rhs);
64  return *this;
65  }
66 
68  RouteUpdatePtr tmp(rhs);
69  swap(tmp);
70  return *this;
71  }
72 
74  RouteUpdate *rt_update = rt_update_;
75  RouteUpdatePtr tmp;
76  tmp.swap(*this);
77  return rt_update;
78  }
79 
80  void swap(RouteUpdatePtr &rhs) {
81  std::swap(rt_update_, rhs.rt_update_);
82  }
83 
84  operator Proxy() {
85  Proxy proxy;
86  std::swap(proxy.rt_update, rt_update_);
87  return proxy;
88  }
89 
90 private:
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 //
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.
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.
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.
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
159  RouteUpdate *rt_update,
160  UpdateCmp cmp, bool *duplicate);
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 
189 
191 };
192 
193 #endif // SRC_BGP_BGP_UPDATE_MONITOR_H_
RouteUpdatePtr & operator=(RouteUpdatePtr &rhs)
RouteUpdate * operator->()
RouteUpdate * release()
boost::function< bool(const RouteUpdate *)> UpdateCmp
DBState * GetRouteUpdateAndDequeue(DBEntryBase *db_entry, RouteUpdate *rt_update, UpdateCmp cmp, bool *duplicate)
void SetEntryState(DBEntryBase *db_entry, DBState *dbstate)
DBState * GetUpdateListAndDequeue(DBEntryBase *db_entry, UpdateList *uplist)
bool RouteStateMergeUpdate(DBEntryBase *db_entry, RouteUpdate *rt_update, RouteState *rstate)
RibUpdateMonitor(RibOut *ribout, QueueVec *queue_vec)
DBState * GetDBStateAndDequeue(DBEntryBase *db_entry, UpdateCmp cmp, bool *duplicate)
RouteUpdatePtr & operator=(Proxy rhs)
RouteUpdatePtr(RouteUpdatePtr &rhs)
RouteUpdatePtr(Proxy rhs)
void RouteStateClearPeerSet(DBEntryBase *db_entry, RouteState *rstate, const RibPeerSet &mleave)
bool UpdateListMergeUpdate(DBEntryBase *db_entry, RouteUpdate *rt_update, UpdateList *uplist)
bool RouteUpdateMergeUpdate(DBEntryBase *db_entry, RouteUpdate *rt_update, RouteUpdate *current_rt_update)
RouteUpdatePtr GetNextUpdate(int queue_id, UpdateEntry *upentry)
void UpdateInfoSListClearBits(UpdateInfoSList &uinfo_slist, const RibPeerSet &clear)
bool EnqueueUpdate(DBEntryBase *db_entry, RouteUpdate *rt_update, UpdateList *uplist=NULL)
RouteUpdatePtr GetNextEntry(int queue_id, UpdateEntry *upentry, UpdateEntry **next_upentry_p)
RouteUpdatePtr GetAttrNext(int queue_id, UpdateInfo *current_uinfo, UpdateInfo **next_uinfo_p)
bool GetPeerSetCurrentAndScheduled(DBEntryBase *db_entry, int queue_id, RibPeerSet *mcurrent, RibPeerSet *mscheduled)
bool MergeUpdate(DBEntryBase *db_entry, RouteUpdate *rt_update)
bool UpdateListClearPeerSet(DBEntryBase *db_entry, UpdateList *uplist, const RibPeerSet &mleave)
RouteUpdate * rt_update_
void ClearEntryState(DBEntryBase *db_entry)
void ClearPeerSetCurrentAndScheduled(DBEntryBase *db_entry, const RibPeerSet &mleave)
bool RouteUpdateClearPeerSet(DBEntryBase *db_entry, RouteUpdate *rt_update, const RibPeerSet &mleave)
void DequeueUpdate(RouteUpdate *rt_update)
DISALLOW_COPY_AND_ASSIGN(RibUpdateMonitor)
void swap(RouteUpdatePtr &rhs)
void AdvertiseSListClearBits(AdvertiseSList &adv_slist, const RibPeerSet &clear)
std::vector< UpdateQueue * > QueueVec