-
Notifications
You must be signed in to change notification settings - Fork 390
/
agent_route.h
321 lines (268 loc) · 11.1 KB
/
agent_route.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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
/*
* Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
*/
#ifndef vnsw_agent_route_hpp
#define vnsw_agent_route_hpp
#include <sys/types.h>
#include <sys/socket.h>
#include <net/ethernet.h>
#include <net/address.h>
#include <base/lifetime.h>
#include <base/patricia.h>
#include <base/task_annotations.h>
#include <cmn/agent_cmn.h>
#include <cmn/agent.h>
#include <agent_types.h>
#include <route/route.h>
#include <route/table.h>
#include <oper/interface_common.h>
#include <oper/nexthop.h>
#include <oper/peer.h>
#include <oper/agent_types.h>
#include <oper/multicast.h>
#include <controller/controller_peer.h>
#include <sandesh/sandesh_trace.h>
class AgentRoute;
class AgentPath;
class Peer;
struct AgentRouteKey : public AgentKey {
AgentRouteKey(const Peer *peer, const std::string &vrf_name) :
AgentKey(), peer_(peer), vrf_name_(vrf_name) { }
virtual ~AgentRouteKey() { }
virtual Agent::RouteTableType GetRouteTableType() = 0;
virtual std::string ToString() const = 0;
virtual AgentRoute *AllocRouteEntry(VrfEntry *vrf,
bool is_multicast) const = 0;
virtual AgentRouteKey *Clone() const = 0;
const std::string &vrf_name() const { return vrf_name_; }
const Peer *peer() const { return peer_; }
void set_peer(const Peer *peer) {peer_ = peer;}
const Peer *peer_;
std::string vrf_name_;
DISALLOW_COPY_AND_ASSIGN(AgentRouteKey);
};
struct AgentRouteData : public AgentData {
enum Type {
ADD_DEL_CHANGE,
ROUTE_PREFERENCE_CHANGE,
IPAM_SUBNET,
};
AgentRouteData(bool is_multicast) : type_(ADD_DEL_CHANGE),
is_multicast_(is_multicast) { }
AgentRouteData(Type type, bool is_multicast):
type_(type), is_multicast_(is_multicast) { }
virtual ~AgentRouteData() { }
virtual std::string ToString() const = 0;
virtual AgentPath *CreateAgentPath(const Peer *peer, AgentRoute *rt) const;
virtual bool AddChangePath(Agent *agent, AgentPath *path,
const AgentRoute *rt) = 0;
virtual bool IsPeerValid(const AgentRouteKey *key) const;
virtual std::string InvalidPeerMsg(const AgentRouteKey *key) const;
virtual bool UpdateRoute(AgentRoute *rt) {return false;}
bool is_multicast() const {return is_multicast_;}
Type type_;
bool is_multicast_;
DISALLOW_COPY_AND_ASSIGN(AgentRouteData);
};
struct RouteComparator {
bool operator() (const AgentRoute *rt1, const AgentRoute *rt2);
};
struct NHComparator {
bool operator() (const NextHop *nh1, const NextHop *nh2);
};
struct RouteTableWalkerState {
RouteTableWalkerState(LifetimeActor *actor) : rt_delete_ref_(this, actor) {
}
~RouteTableWalkerState() {
rt_delete_ref_.Reset(NULL);
}
void ManagedDelete() { }
LifetimeRef<RouteTableWalkerState> rt_delete_ref_;
};
// Agent implements multiple route tables - inet4-unicast, inet4-multicast,
// bridge. This base class contains common code for all route tables
class AgentRouteTable : public RouteTable {
public:
static const int kPartitionCount = 1;
typedef std::set<const AgentRoute *, RouteComparator> UnresolvedRouteTree;
typedef std::set<const NextHop *, NHComparator> UnresolvedNHTree;
AgentRouteTable(DB *db, const std::string &name);
virtual ~AgentRouteTable();
virtual int PartitionCount() const { return kPartitionCount; }
virtual std::auto_ptr<DBEntry> AllocEntry(const DBRequestKey *k) const;
virtual size_t Hash(const DBEntry *entry) const {return 0;}
virtual size_t Hash(const DBRequestKey *key) const {return 0;}
virtual Agent::RouteTableType GetTableType() const = 0;
virtual std::string GetTableName() const = 0;
virtual void ProcessDelete(AgentRoute *rt) { }
virtual void ProcessAdd(AgentRoute *rt) { }
//Entry notification
virtual void NotifyEntry(AgentRoute *entry);
//Can be used for operations related to updation of route.
virtual void UpdateDependants(AgentRoute *entry) { }
//Can be used for operations resulting from deletion of route.
virtual void PreRouteDelete(AgentRoute *entry) { }
virtual AgentSandeshPtr GetAgentSandesh(const AgentSandeshArguments *args,
const std::string &context) {
return AgentSandeshPtr();
}
// Unresolved route tree accessors
UnresolvedRouteTree::const_iterator unresolved_route_begin() const {
return unresolved_rt_tree_.begin();
}
UnresolvedRouteTree::const_iterator unresolved_route_end() const {
return unresolved_rt_tree_.end();
}
int unresolved_route_size() const { return unresolved_rt_tree_.size(); }
// Unresolved NH tree accessors
void AddUnresolvedNH(const NextHop *);
void RemoveUnresolvedNH(const NextHop *);
void EvaluateUnresolvedNH(void);
UnresolvedNHTree::const_iterator unresolved_nh_begin() const {
return unresolved_nh_tree_.begin();
}
UnresolvedNHTree::const_iterator unresolved_nh_end() const {
return unresolved_nh_tree_.end();
}
Agent *agent() const { return agent_; }
const std::string &vrf_name() const;
uint32_t vrf_id() const {return vrf_id_;}
VrfEntry *vrf_entry() const;
AgentRoute *FindActiveEntry(const AgentRouteKey *key);
// Set VRF for the route-table
void SetVrf(VrfEntry * vrf);
// Helper functions to delete routes
bool DeleteAllBgpPath(DBTablePartBase *part, DBEntryBase *entry);
bool DelExplicitRouteWalkerCb(DBTablePartBase *part, DBEntryBase *entry);
// Lifetime actor routines
LifetimeActor *deleter();
void ManagedDelete();
virtual void RetryDelete();
// Process DBRequest inline
void Process(DBRequest &req);
// Path comparator
static bool PathSelection(const Path &path1, const Path &path2);
static const std::string &GetSuffix(Agent::RouteTableType type);
void DeletePathFromPeer(DBTablePartBase *part, AgentRoute *rt,
AgentPath *path);
//const Peer *peer);
//Stale path handling
void StalePathFromPeer(DBTablePartBase *part, AgentRoute *rt,
const Peer *peer);
void SquashStalePaths(AgentRoute *rt, const AgentPath *path);
private:
class DeleteActor;
void AddUnresolvedRoute(const AgentRoute *rt);
void RemoveUnresolvedRoute(const AgentRoute *rt);
void EvaluateUnresolvedRoutes(void);
void DeleteRouteDone(DBTableBase *base, RouteTableWalkerState *state);
void Input(DBTablePartition *part, DBClient *client, DBRequest *req);
Agent *agent_;
UnresolvedRouteTree unresolved_rt_tree_;
UnresolvedNHTree unresolved_nh_tree_;
VrfEntryRef vrf_entry_;
// VRF is stored to identify which VRF this table belonged to
// in case lifetimeactor has reset the vrf_.
uint32_t vrf_id_;
boost::scoped_ptr<DeleteActor> deleter_;
LifetimeRef<AgentRouteTable> vrf_delete_ref_;
DISALLOW_COPY_AND_ASSIGN(AgentRouteTable);
};
// Base class for all Route entries in agent
class AgentRoute : public Route {
public:
enum Trace {
ADD,
DELETE,
ADD_PATH,
DELETE_PATH,
CHANGE_PATH,
STALE_PATH,
};
typedef DependencyList<AgentRoute, AgentRoute> RouteDependencyList;
typedef DependencyList<NextHop, AgentRoute> TunnelNhDependencyList;
AgentRoute(VrfEntry *vrf, bool is_multicast) :
Route(), vrf_(vrf), is_multicast_(is_multicast) { }
virtual ~AgentRoute() { }
// Virtual functions from base DBEntry
virtual bool IsLess(const DBEntry &rhs) const;
virtual KeyPtr GetDBRequestKey() const = 0;
virtual void SetKey(const DBRequestKey *key) = 0;
// Virtual functions defined by AgentRoute
virtual int CompareTo(const Route &rhs) const = 0;
virtual Agent::RouteTableType GetTableType() const = 0;
virtual bool DBEntrySandesh(Sandesh *sresp, bool stale) const = 0;
virtual std::string ToString() const = 0;
virtual const std::string GetAddressString() const = 0;
virtual bool ReComputePathDeletion(AgentPath *path) {return false;}
virtual bool ReComputePathAdd(AgentPath *path) {return false;}
virtual uint32_t GetActiveLabel() const;
virtual AgentPath *FindPathUsingKeyData(const AgentRouteKey *key,
const AgentRouteData *data) const;
virtual AgentPath *FindPath(const Peer *peer) const;
virtual void DeletePathUsingKeyData(const AgentRouteKey *key,
const AgentRouteData *data,
bool force_delete);
virtual bool RecomputeRoutePath(Agent *agent,
DBTablePartition *part,
AgentPath *path,
AgentRouteData *data) {return false;}
// Accessor functions
bool is_multicast() const {return is_multicast_;}
VrfEntry *vrf() const {return vrf_.get();}
uint32_t vrf_id() const;
AgentPath *FindLocalVmPortPath() const;
AgentPath *FindStalePath();
const AgentPath *GetActivePath() const;
const NextHop *GetActiveNextHop() const;
const std::string &dest_vn_name() const;
bool IsRPFInvalid() const;
void EnqueueRouteResync() const;
void ResyncTunnelNextHop();
bool HasUnresolvedPath();
bool Sync(void);
//TODO Move dependantroutes and nh to inet4
void UpdateDependantRoutes();// analogous to updategatewayroutes
bool IsDependantRouteEmpty() { return dependant_routes_.empty(); }
bool IsTunnelNHListEmpty() { return tunnel_nh_list_.empty(); }
void FillTrace(RouteInfo &route, Trace event, const AgentPath *path);
bool WaitForTraffic() const;
virtual uint8_t plen() const { return 0; }
protected:
void SetVrf(VrfEntryRef vrf) { vrf_ = vrf; }
void RemovePathInternal(AgentPath *path);
void RemovePath(AgentPath *path);
void InsertPath(const AgentPath *path);
void DeletePathInternal(AgentPath *path);
private:
friend class AgentRouteTable;
bool ProcessPath(Agent *agent,
DBTablePartition *part,
AgentPath *path,
AgentRouteData *data);
VrfEntryRef vrf_;
// Unicast table can contain routes for few multicast address
// (ex. subnet multicast). Flag to specify if this is multicast route
bool is_multicast_;
DEPENDENCY_LIST(AgentRoute, AgentRoute, dependant_routes_);
DEPENDENCY_LIST(NextHop, AgentRoute, tunnel_nh_list_);
DISALLOW_COPY_AND_ASSIGN(AgentRoute);
};
#define AGENT_DBWALK_TRACE_BUF "AgentDBwalkTrace"
#define AGENT_ROUTE_TRACE_BUF "OperRouteTrace"
extern SandeshTraceBufferPtr AgentDBwalkTraceBuf;
extern SandeshTraceBufferPtr AgentRouteTraceBuf;
#define AGENT_DBWALK_TRACE(obj, ...) do { \
obj::TraceMsg(AgentDBwalkTraceBuf, __FILE__, __LINE__, ##__VA_ARGS__); \
} while (0);
#define GETPEERNAME(peer) (peer)? peer->GetName() : ""
#define AGENT_ROUTE_LOG(msg, route, vrf, peer_info)\
do {\
AgentRouteLog::TraceMsg(AgentRouteTraceBuf, __FILE__, __LINE__, msg, route,\
vrf, peer_info);\
} while(false);\
#define ROUTE_OPER_TRACE(type, rt_info)\
do {\
OperRoute::TraceMsg(AgentRouteTraceBuf, __FILE__, __LINE__, rt_info);\
} while(false);\
#endif