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