OpenSDN source code
routepath_replicator.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3  * Copyright Contributors to the OpenSDN project
4  */
5 
6 #ifndef SRC_BGP_ROUTING_INSTANCE_ROUTEPATH_REPLICATOR_H_
7 #define SRC_BGP_ROUTING_INSTANCE_ROUTEPATH_REPLICATOR_H_
8 
9 #include <boost/ptr_container/ptr_map.hpp>
10 #include <sandesh/sandesh_trace.h>
11 
12 #include <atomic>
13 #include <list>
14 #include <map>
15 #include <set>
16 #include <string>
17 #include <vector>
18 #include <mutex>
19 
20 #include "base/lifetime.h"
21 #include "base/util.h"
22 #include "bgp/bgp_path.h"
23 #include "db/db_entry.h"
24 #include "db/db_table.h"
25 
26 class BgpRoute;
27 class BgpServer;
28 class BgpTable;
29 class RtGroup;
31 class RouteTarget;
32 
33 //
34 // This keeps track of a RoutePathReplicator's listener state for a BgpTable.
35 // An instance is created for each VRF table and for the VPN table.
36 //
37 // An entry for VPN table is created when RoutePathReplicator is initialized.
38 // An entry for a VRF table is created when processing a Join for the first
39 // export route target for the VRF.
40 // TableState is removed when a Bgp table is deleted.
41 // TableState takes a delete reference to the BgpTable and DeleteActor of the
42 // TableState manages the unregister of this listener from the BgpTable and
43 // delete of TableState object.
44 //
45 // A TableState entry keeps track of all the export route targets for a VRF
46 // by maintaining the GroupList. TableState cannot be deleted if GroupList
47 // is non-empty and table has replicated routes. Replicated routes are tracked
48 // using the DBStateCount of this listener
49 //
50 class TableState {
51 public:
52  typedef std::set<RtGroup *> GroupList;
53 
55  ~TableState();
56 
57  void ManagedDelete();
58  bool MayDelete() const;
59  void RetryDelete();
60 
62  const LifetimeActor *deleter() const;
63  bool deleted() const;
64 
65  void AddGroup(RtGroup *group);
66  void RemoveGroup(RtGroup *group);
67  const RtGroup *FindGroup(RtGroup *group) const;
68  bool empty() const { return list_.empty(); }
69 
70  // Generation of the table's export route target list, bumped on every
71  // change to it. Replication compares it against the value recorded in
72  // RtReplicated to tell whether the paths replicated earlier still carry
73  // the current targets. Written from the config tasks, read from
74  // db::DBTable.
75  uint64_t export_target_gen() const { return export_target_gen_.load(); }
77 
82  }
83 
84  uint32_t route_count() const;
85 
87  return replicator_;
88  }
89 
91  return replicator_;
92  }
93 
94  BgpTable *table() const {
95  return table_;
96  }
97 
99  return table_;
100  }
101 
103  return walk_ref_;
104  }
105 
107  return walk_ref_;
108  }
109 
112  }
113 
114 private:
115  class DeleteActor;
119  boost::scoped_ptr<DeleteActor> deleter_;
122  std::atomic<uint64_t> export_target_gen_;
124 
126 };
127 
128 //
129 // This keeps track of the replication state for a route in the primary table.
130 // The ReplicatedRtPathList is a set of SecondaryRouteInfo, where each element
131 // represents a secondary path in a secondary table. An entry is added to the
132 // set when a path is replicated to a secondary table removed when it's not
133 // replicated anymore.
134 //
135 // Changes to ReplicatedRtPathList may be triggered by changes in the primary
136 // route, changes in the export targets of the primary table or changes in the
137 // import targets of secondary tables.
138 //
139 // A RtReplicated is deleted when the route in the primary table is no longer
140 // replicated to any secondary tables.
141 //
142 class RtReplicated : public DBState {
143 public:
145  public:
147  const IPeer *peer_;
148  uint32_t path_id_;
151 
152  SecondaryRouteInfo(BgpTable *table, const IPeer *peer,
153  uint32_t path_id, BgpPath::PathSource src, BgpRoute *rt)
154  : table_(table),
155  peer_(peer),
156  path_id_(path_id),
157  src_(src),
158  rt_(rt) {
159  }
160  int CompareTo(const SecondaryRouteInfo &rhs) const {
161  KEY_COMPARE(table_, rhs.table_);
162  KEY_COMPARE(peer_, rhs.peer_);
164  KEY_COMPARE(src_, rhs.src_);
165  KEY_COMPARE(rt_, rhs.rt_);
166  return 0;
167  }
168  bool operator<(const SecondaryRouteInfo &rhs) const {
169  return (CompareTo(rhs) < 0);
170  }
171  bool operator>(const SecondaryRouteInfo &rhs) const {
172  return (CompareTo(rhs) > 0);
173  }
174 
175  std::string ToString() const;
176  };
177 
178  typedef std::set<SecondaryRouteInfo> ReplicatedRtPathList;
179 
180  explicit RtReplicated(RoutePathReplicator *replicator);
181 
182  void AddRouteInfo(BgpTable *table, BgpRoute *rt,
183  ReplicatedRtPathList::const_iterator it);
184  void DeleteRouteInfo(BgpTable *table, BgpRoute *rt,
185  ReplicatedRtPathList::const_iterator it);
186 
187  const ReplicatedRtPathList &GetList() const { return replicate_list_; }
189  std::vector<std::string> GetTableNameList(const BgpPath *path) const;
190 
191  // TableState::export_target_gen of the primary table as of the last time
192  // the route was replicated.
193  uint64_t export_target_gen() const { return export_target_gen_; }
194  void set_export_target_gen(uint64_t gen) { export_target_gen_ = gen; }
195 
196 private:
200 };
201 
202 //
203 // This class implements functionality to import and export BgpPaths between
204 // VRF BgpTables and a VPN BgpTable for a given address family. The exporting
205 // table is referred to as the primary table and the importing tables are
206 // referred to as secondary tables.
207 //
208 // The rules for importing and exporting paths are based on route targets of
209 // the VRF tables and the route targets in VPN routes. They can be summarized
210 // as follows:
211 //
212 // o The VPN table unconditionally imports routes from all VRF tables.
213 // o The VPN table potentially exports routes to all VRF tables.
214 // o A path in a VRF table is considered to have export targets of the table.
215 // o A path in the VPN table has route targets in it's attributes.
216 // o A path in a primary table is imported into a secondary table if one or
217 // o more of the targets for the path is in the list of import targets for
218 // the secondary table.
219 // o Secondary paths are never exported to other secondary tables.
220 //
221 // Dependency tracking mechanisms are needed to implement replication in an
222 // an efficient manner. RoutePathReplicator does the following:
223 //
224 // 1. When an export target is added to or removed from a VRF table, walk all
225 // routes in the VRF table to re-evaluate the new set of secondary paths.
226 // The DBTableWalkMgr provides this functionality.
227 // 2. When an import target is added to or removed from a VRF table, walk all
228 // VRF tables that have the target in question as an export target. The
229 // list of tables that export a target is maintained in the RTargetGroupMgr.
230 // This list is updated by the replicator (by calling RTargetGroupMgr APIs)
231 // based on configuration changes in the routing instance.
232 // 3. When an import target is added to or removed from a VRF tables, walk all
233 // VPN routes with the target in question. This dependency is maintained
234 // by RTargetGroupMgr.
235 // 4. When a route is updated, calculate new set of secondary paths by going
236 // through all VRF tables that import one of the targets for the route in
237 // question. The list of VRF tables is obtained from the RTargetGroupMgr.
238 // 5. When a route is updated, remove secondary paths that are not required
239 // anymore. The list of previous secondary paths for a primary route is
240 // maintained using RtReplicated and reconciled/synchronized with the new
241 // list obtained from 4.
242 //
243 // The TableStateList keeps track of the TableState for each VRF from which
244 // routes could be exported. It also has an entry for the TableState for the
245 // VPN table. This entry is created when the replicator is initialized and
246 // deleted during shutdown.
247 //
248 // The UnregTableList keeps track of tables for which we need to delete the
249 // TableState. Requests are enqueued from the db::DBTable task when a table
250 // walk finishes and the TableState is empty.
251 //
252 // A mutex is used to serialize access from multiple bgp::ConfigHelper tasks.
253 //
255 public:
257  virtual ~RoutePathReplicator();
258 
259  void Initialize();
260  void Join(BgpTable *table, const RouteTarget &rt, bool import);
261  void Leave(BgpTable *table, const RouteTarget &rt, bool import);
262 
263  std::vector<std::string> GetReplicatedTableNameList(const BgpTable *table,
264  const BgpRoute *route, const BgpPath *path) const;
266  BgpRoute *rt) const;
267 
268 private:
269  friend class ReplicationTest;
270  friend class BGPaaSRDTest;
271  friend class RtReplicated;
272  friend class TableState;
273 
274  typedef std::map<BgpTable *, TableState *> TableStateList;
275  typedef std::set<BgpTable *> UnregTableList;
276 
277  void RequestWalk(BgpTable *table);
278  void BulkReplicationDone(DBTableBase *dbtable);
280 
281  TableState *AddTableState(BgpTable *table, RtGroup *group = NULL);
282  void RemoveTableState(BgpTable *table, RtGroup *group);
286  const TableState *FindTableState(const BgpTable *table) const;
287 
288  void JoinVpnTable(RtGroup *group);
289  void LeaveVpnTable(RtGroup *group);
290 
291  bool RouteListener(TableState *ts, DBTablePartBase *root,
292  DBEntryBase *entry);
294  const RtReplicated::SecondaryRouteInfo &rtinfo);
295  void DBStateSync(BgpTable *table, TableState *ts, BgpRoute *rt,
296  RtReplicated *dbstate,
297  const RtReplicated::ReplicatedRtPathList *future);
298 
299  BgpServer *server() { return server_; }
300  Address::Family family() const { return family_; }
301  const BgpServer *server() const { return server_; }
302 
304  std::mutex mutex_;
309 
311 };
312 
313 #endif // SRC_BGP_ROUTING_INSTANCE_ROUTEPATH_REPLICATOR_H_
Family
Definition: address.h:25
PathSource
Definition: bgp_path.h:38
static const int kInvalidId
Definition: db_table.h:65
int ListenerId
Definition: db_table.h:63
boost::intrusive_ptr< DBTableWalk > DBTableWalkRef
Definition: db_table.h:170
Definition: ipeer.h:187
void DeleteSecondaryPath(BgpTable *table, BgpRoute *rt, const RtReplicated::SecondaryRouteInfo &rtinfo)
SandeshTraceBufferPtr trace_buf_
std::map< BgpTable *, TableState * > TableStateList
void DeleteTableState(BgpTable *table)
void LeaveVpnTable(RtGroup *group)
RoutePathReplicator(BgpServer *server, Address::Family family)
void RemoveTableState(BgpTable *table, RtGroup *group)
void UnregisterTableState(BgpTable *table)
DISALLOW_COPY_AND_ASSIGN(RoutePathReplicator)
void DBStateSync(BgpTable *table, TableState *ts, BgpRoute *rt, RtReplicated *dbstate, const RtReplicated::ReplicatedRtPathList *future)
TableStateList table_state_list_
TableState * AddTableState(BgpTable *table, RtGroup *group=NULL)
std::set< BgpTable * > UnregTableList
Address::Family family() const
const RtReplicated * GetReplicationState(BgpTable *table, BgpRoute *rt) const
void BulkReplicationDone(DBTableBase *dbtable)
TableState * FindTableState(BgpTable *table)
void JoinVpnTable(RtGroup *group)
void Join(BgpTable *table, const RouteTarget &rt, bool import)
std::vector< std::string > GetReplicatedTableNameList(const BgpTable *table, const BgpRoute *route, const BgpPath *path) const
const BgpServer * server() const
void RequestWalk(BgpTable *table)
bool RouteListener(TableState *ts, DBTablePartBase *root, DBEntryBase *entry)
void Leave(BgpTable *table, const RouteTarget &rt, bool import)
void DeleteRouteInfo(BgpTable *table, BgpRoute *rt, ReplicatedRtPathList::const_iterator it)
void AddRouteInfo(BgpTable *table, BgpRoute *rt, ReplicatedRtPathList::const_iterator it)
ReplicatedRtPathList replicate_list_
RtReplicated(RoutePathReplicator *replicator)
RoutePathReplicator * replicator_
ReplicatedRtPathList * GetMutableList()
uint64_t export_target_gen_
void set_export_target_gen(uint64_t gen)
const ReplicatedRtPathList & GetList() const
std::set< SecondaryRouteInfo > ReplicatedRtPathList
uint64_t export_target_gen() const
std::vector< std::string > GetTableNameList(const BgpPath *path) const
RoutePathReplicator * replicator_
void RemoveGroup(RtGroup *group)
DISALLOW_COPY_AND_ASSIGN(TableState)
const DBTable::DBTableWalkRef & walk_ref() const
boost::scoped_ptr< DeleteActor > deleter_
void AddGroup(RtGroup *group)
bool MayDelete() const
TableState(RoutePathReplicator *replicator, BgpTable *table)
BgpTable * table()
bool deleted() const
std::atomic< uint64_t > export_target_gen_
bool empty() const
BgpTable * table() const
void bump_export_target_gen()
DBTableBase::ListenerId listener_id_
void set_listener_id(DBTableBase::ListenerId listener_id)
const RtGroup * FindGroup(RtGroup *group) const
LifetimeActor * deleter()
DBTable::DBTableWalkRef walk_ref_
std::set< RtGroup * > GroupList
uint64_t export_target_gen() const
LifetimeRef< TableState > table_delete_ref_
const RoutePathReplicator * replicator() const
DBTableBase::ListenerId listener_id() const
uint32_t route_count() const
RoutePathReplicator * replicator()
DBTable::DBTableWalkRef & walk_ref()
void set_walk_ref(DBTable::DBTableWalkRef walk_ref)
boost::shared_ptr< TraceBuffer< SandeshTrace > > SandeshTraceBufferPtr
Definition: sandesh_trace.h:19
int CompareTo(const SecondaryRouteInfo &rhs) const
bool operator<(const SecondaryRouteInfo &rhs) const
bool operator>(const SecondaryRouteInfo &rhs) const
SecondaryRouteInfo(BgpTable *table, const IPeer *peer, uint32_t path_id, BgpPath::PathSource src, BgpRoute *rt)
#define KEY_COMPARE(x, y)
Definition: util.h:71