Line data Source code
1 : /*
2 : * Copyright (c) 2018 Juniper Networks, Inc. All rights reserved.
3 : */
4 :
5 : #ifndef __AGENT_PKT_FLOW_MGMT_TREE_H__
6 : #define __AGENT_PKT_FLOW_MGMT_TREE_H__
7 :
8 : #include <cstdlib>
9 : #include <map>
10 : #include <mutex>
11 : #include <pkt/flow_mgmt/flow_mgmt_key.h>
12 :
13 : class FlowMgmtKeyNode;
14 : class FlowMgmtEntry;
15 :
16 : class BgpAsAServiceFlowMgmtRequest;
17 :
18 : typedef std::map<FlowMgmtKey *, FlowMgmtKeyNode *, FlowMgmtKeyCmp> FlowMgmtKeyTree;
19 :
20 : class FlowMgmtTree {
21 : public:
22 : typedef std::map<FlowMgmtKey *, FlowMgmtEntry *, FlowMgmtKeyCmp> Tree;
23 30 : FlowMgmtTree(FlowMgmtManager *mgr) : mgr_(mgr) { }
24 30 : virtual ~FlowMgmtTree() {
25 30 : assert(tree_.size() == 0);
26 30 : }
27 :
28 : // Add a flow into dependency tree for an object
29 : // Creates an entry if not already present in the tree
30 : virtual bool Add(FlowMgmtKey *key, FlowEntry *flow,
31 : FlowMgmtKeyNode *node);
32 : // Delete a flow from dependency tree for an object
33 : // Entry is deleted after all flows dependent on the entry are deleted
34 : // and DBEntry delete message is got from FlowTable
35 : virtual bool Delete(FlowMgmtKey *key, FlowEntry *flow,
36 : FlowMgmtKeyNode *node);
37 : virtual void InsertEntry(FlowMgmtKey *key, FlowMgmtEntry *entry);
38 : virtual void RemoveEntry(Tree::iterator it);
39 :
40 : // Handle DBEntry add
41 : virtual bool OperEntryAdd(const FlowMgmtRequest *req, FlowMgmtKey *key);
42 : // Handle DBEntry change
43 : virtual bool OperEntryChange(const FlowMgmtRequest *req, FlowMgmtKey *key);
44 : // Handle DBEntry delete
45 : virtual bool OperEntryDelete(const FlowMgmtRequest *req, FlowMgmtKey *key);
46 :
47 : // Try delete a DBEntry
48 : virtual bool RetryDelete(FlowMgmtKey *key);
49 :
50 : // Get all Keys relavent for the tree and store them into FlowMgmtKeyTree
51 : virtual void ExtractKeys(FlowEntry *flow, FlowMgmtKeyTree *tree) = 0;
52 : // Allocate a FlowMgmtEntry for the tree
53 : virtual FlowMgmtEntry *Allocate(const FlowMgmtKey *key) = 0;
54 :
55 : // Called just before entry is deleted. Used to implement cleanup operations
56 : virtual void FreeNotify(FlowMgmtKey *key, uint32_t gen_id);
57 :
58 : FlowMgmtEntry *Locate(FlowMgmtKey *key);
59 : FlowMgmtEntry *Find(FlowMgmtKey *key);
60 : FlowMgmtKey *LowerBound(FlowMgmtKey *key);
61 0 : Tree &tree() { return tree_; }
62 48 : FlowMgmtManager *mgr() const { return mgr_; }
63 : static bool AddFlowMgmtKey(FlowMgmtKeyTree *tree, FlowMgmtKey *key);
64 :
65 : protected:
66 : bool TryDelete(FlowMgmtKey *key, FlowMgmtEntry *entry);
67 : Tree tree_;
68 : FlowMgmtManager *mgr_;
69 :
70 : private:
71 : DISALLOW_COPY_AND_ASSIGN(FlowMgmtTree);
72 : };
73 :
74 : ////////////////////////////////////////////////////////////////////////////
75 : // Object specific information below
76 : ////////////////////////////////////////////////////////////////////////////
77 : class AclFlowMgmtTree : public FlowMgmtTree {
78 : public:
79 3 : AclFlowMgmtTree(FlowMgmtManager *mgr) : FlowMgmtTree(mgr) { }
80 3 : virtual ~AclFlowMgmtTree() { }
81 :
82 : bool Add(FlowMgmtKey *key, FlowEntry *flow, FlowMgmtKey *old_key,
83 : FlowMgmtKeyNode *node);
84 : bool Delete(FlowMgmtKey *key, FlowEntry *flow,
85 : FlowMgmtKeyNode *node);
86 : void ExtractKeys(FlowEntry *flow, FlowMgmtKeyTree *tree,
87 : const MatchAclParamsList *acl_list);
88 : void ExtractKeys(FlowEntry *flow, FlowMgmtKeyTree *tree);
89 : FlowMgmtEntry *Allocate(const FlowMgmtKey *key);
90 :
91 : private:
92 : DISALLOW_COPY_AND_ASSIGN(AclFlowMgmtTree);
93 : };
94 :
95 : class VnFlowMgmtTree : public FlowMgmtTree {
96 : public:
97 3 : VnFlowMgmtTree(FlowMgmtManager *mgr) : FlowMgmtTree(mgr) {}
98 3 : virtual ~VnFlowMgmtTree() {}
99 :
100 : void ExtractKeys(FlowEntry *flow, FlowMgmtKeyTree *tree);
101 : FlowMgmtEntry *Allocate(const FlowMgmtKey *key);
102 :
103 : void VnFlowCounters(const VnEntry *vn,
104 : uint32_t *ingress_flow_count,
105 : uint32_t *egress_flow_count);
106 : void RemoveEntry(Tree::iterator it);
107 : void InsertEntry(FlowMgmtKey *key, FlowMgmtEntry *entry);
108 :
109 : private:
110 : // We need to support query of counters in VN from other threads.
111 : // So, implement synchronization on access to VN Flow Tree
112 : std::mutex mutex_;
113 : DISALLOW_COPY_AND_ASSIGN(VnFlowMgmtTree);
114 : };
115 :
116 : class InterfaceFlowMgmtTree : public FlowMgmtTree {
117 : public:
118 3 : InterfaceFlowMgmtTree(FlowMgmtManager *mgr) : FlowMgmtTree(mgr) {}
119 3 : virtual ~InterfaceFlowMgmtTree() {}
120 :
121 : void ExtractKeys(FlowEntry *flow, FlowMgmtKeyTree *tree);
122 : FlowMgmtEntry *Allocate(const FlowMgmtKey *key);
123 : void InterfaceFlowCount(const Interface *itf, uint64_t *created,
124 : uint64_t *aged, uint32_t *active_flows);
125 : void InsertEntry(FlowMgmtKey *key, FlowMgmtEntry *entry);
126 : void RemoveEntry(Tree::iterator it);
127 :
128 : private:
129 : // We need to support query of counters in Interface from other threads.
130 : // So, implement synchronization on access to Interface Flow Tree
131 : std::mutex mutex_;
132 : DISALLOW_COPY_AND_ASSIGN(InterfaceFlowMgmtTree);
133 : };
134 :
135 : class NhFlowMgmtTree : public FlowMgmtTree {
136 : public:
137 3 : NhFlowMgmtTree(FlowMgmtManager *mgr) : FlowMgmtTree(mgr) {}
138 3 : virtual ~NhFlowMgmtTree() {}
139 :
140 : void ExtractKeys(FlowEntry *flow, FlowMgmtKeyTree *tree);
141 : FlowMgmtEntry *Allocate(const FlowMgmtKey *key);
142 :
143 : private:
144 : DISALLOW_COPY_AND_ASSIGN(NhFlowMgmtTree);
145 : };
146 :
147 : class RouteFlowMgmtTree : public FlowMgmtTree {
148 : public:
149 9 : RouteFlowMgmtTree(FlowMgmtManager *mgr) : FlowMgmtTree(mgr) { }
150 9 : virtual ~RouteFlowMgmtTree() { }
151 : virtual bool HasVrfFlows(uint32_t vrf_id, Agent::RouteTableType type) = 0;
152 :
153 : virtual bool Delete(FlowMgmtKey *key, FlowEntry *flow, FlowMgmtKeyNode *node);
154 : virtual bool OperEntryDelete(const FlowMgmtRequest *req, FlowMgmtKey *key);
155 : virtual bool OperEntryAdd(const FlowMgmtRequest *req, FlowMgmtKey *key);
156 :
157 : private:
158 : void SetDBEntry(const FlowMgmtRequest *req, FlowMgmtKey *key);
159 : DISALLOW_COPY_AND_ASSIGN(RouteFlowMgmtTree);
160 : };
161 :
162 : class InetRouteFlowMgmtTree : public RouteFlowMgmtTree {
163 : public:
164 : typedef Patricia::Tree<InetRouteFlowMgmtKey, &InetRouteFlowMgmtKey::node_,
165 : InetRouteFlowMgmtKey::KeyCmp> LpmTree;
166 :
167 6 : InetRouteFlowMgmtTree(FlowMgmtManager *mgr) : RouteFlowMgmtTree(mgr) { }
168 6 : virtual ~InetRouteFlowMgmtTree() { }
169 :
170 : void ExtractKeys(FlowEntry *flow, FlowMgmtKeyTree *tree, uint32_t vrf,
171 : const IpAddress &ip, uint8_t plen);
172 : void ExtractKeys(FlowEntry *flow, FlowMgmtKeyTree *tree,
173 : const IpAddress &ip, const FlowRouteRefMap *rt_list);
174 : void ExtractKeys(FlowEntry *flow, FlowMgmtKeyTree *tree);
175 :
176 : virtual bool OperEntryAdd(const FlowMgmtRequest *req, FlowMgmtKey *key);
177 : virtual bool OperEntryDelete(const FlowMgmtRequest *req, FlowMgmtKey *key);
178 : FlowMgmtEntry *Allocate(const FlowMgmtKey *key);
179 : bool HasVrfFlows(uint32_t vrf_id, Agent::RouteTableType type);
180 :
181 150 : InetRouteFlowMgmtKey *LPM(const InetRouteFlowMgmtKey *key) {
182 150 : if (key->plen_ == 0)
183 0 : return NULL;
184 150 : return lpm_tree_.LPMFind(key);
185 : }
186 :
187 164 : void AddToLPMTree(InetRouteFlowMgmtKey *key) {
188 : InetRouteFlowMgmtKey *rt_key =
189 164 : static_cast<InetRouteFlowMgmtKey *>(key->Clone());
190 164 : if (lpm_tree_.Insert(rt_key) == false)
191 85 : delete rt_key;
192 164 : }
193 :
194 79 : void DelFromLPMTree(InetRouteFlowMgmtKey *key) {
195 79 : InetRouteFlowMgmtKey *rt_key = lpm_tree_.Find(key);
196 79 : if (rt_key != NULL) {
197 79 : lpm_tree_.Remove(rt_key);
198 79 : delete rt_key;
199 : }
200 79 : }
201 : bool RecomputeCoveringRoute(InetRouteFlowMgmtKey *covering_route,
202 : InetRouteFlowMgmtKey *key);
203 : bool RouteNHChangeEvent(const FlowMgmtRequest *req, FlowMgmtKey *key);
204 :
205 : private:
206 : LpmTree lpm_tree_;
207 : DISALLOW_COPY_AND_ASSIGN(InetRouteFlowMgmtTree);
208 : };
209 :
210 : class BridgeRouteFlowMgmtTree : public RouteFlowMgmtTree {
211 : public:
212 3 : BridgeRouteFlowMgmtTree(FlowMgmtManager *mgr) : RouteFlowMgmtTree(mgr) { }
213 3 : virtual ~BridgeRouteFlowMgmtTree() { }
214 : void ExtractKeys(FlowEntry *flow, FlowMgmtKeyTree *tree);
215 : FlowMgmtEntry *Allocate(const FlowMgmtKey *key);
216 : bool HasVrfFlows(uint32_t vrf_id, Agent::RouteTableType type);
217 :
218 : private:
219 : DISALLOW_COPY_AND_ASSIGN(BridgeRouteFlowMgmtTree);
220 : };
221 :
222 : ////////////////////////////////////////////////////////////////////////////
223 : // Flow Management tree for VRF. VRF tree does not follow the normal pattern
224 : // for other DBEntries.
225 : //
226 : // VRF flow management implements following functions,
227 : // 1. Generate event to delete VRF when all flows for a VRF are deleted
228 : // 2. Implement lifetime reference to Route Table for INET/Bridge DBTables
229 : // The route-table must be present till all flows relavent for the flow are
230 : // present.
231 : // FlowLifetimeRef implements Lifetime actor on the route-table till all
232 : // flows for the route-table are deleted
233 : //
234 : // When a flow-add is got, we dont really check for presence of VRF or not.
235 : // When adding a flow, FlowTable must ensure that VRF is valid at that time
236 : //
237 : // FlowTable module on the other hand, ensures that flow is not added on a
238 : // non-existing or a deleted VRF
239 : //
240 : // The routes used in flow-entry refer to VRF by vrf-id (ex. RouteFlowRefMap).
241 : // Hence, we dont have VRF pointer in all cases. Instead, we store vrf-id as
242 : // key
243 : ////////////////////////////////////////////////////////////////////////////
244 : class VrfFlowMgmtTree : public FlowMgmtTree {
245 : public:
246 : // Build local mapping of vrf-id to VrfEntry mapping.
247 : // The mapping is already maintained in VrfTable. But, we cannot query it
248 : // since we run in parallel to DB Task context
249 : typedef std::map<uint32_t, const VrfEntry *> VrfIdMap;
250 3 : VrfFlowMgmtTree(FlowMgmtManager *mgr) : FlowMgmtTree(mgr) { }
251 3 : virtual ~VrfFlowMgmtTree() { }
252 :
253 : virtual FlowMgmtEntry *Allocate(const FlowMgmtKey *key);
254 : virtual bool OperEntryAdd(const FlowMgmtRequest *req, FlowMgmtKey *key);
255 : virtual bool OperEntryDelete(const FlowMgmtRequest *req, FlowMgmtKey *key);
256 : void DeleteDefaultRoute(const VrfEntry *vrf);
257 : virtual void FreeNotify(FlowMgmtKey *key, uint32_t gen_id);
258 : void RetryDelete(uint32_t vrf_id);
259 : void ExtractKeys(FlowEntry *flow, FlowMgmtKeyTree *tree);
260 :
261 : private:
262 : VrfIdMap id_map_;
263 : DISALLOW_COPY_AND_ASSIGN(VrfFlowMgmtTree);
264 : };
265 :
266 : class BgpAsAServiceFlowMgmtTree : public FlowMgmtTree {
267 : public:
268 : static const int kInvalidCnIndex = -1;
269 6 : BgpAsAServiceFlowMgmtTree(FlowMgmtManager *mgr, int index) :
270 6 : FlowMgmtTree(mgr), index_(index) {}
271 12 : virtual ~BgpAsAServiceFlowMgmtTree() {}
272 :
273 : void ExtractKeys(FlowEntry *flow, FlowMgmtKeyTree *tree);
274 : FlowMgmtEntry *Allocate(const FlowMgmtKey *key);
275 : bool BgpAsAServiceHealthCheckUpdate(Agent *agent,
276 : BgpAsAServiceFlowMgmtKey &key,
277 : BgpAsAServiceFlowMgmtRequest *req);
278 : bool BgpAsAServiceDelete(BgpAsAServiceFlowMgmtKey &key,
279 : const FlowMgmtRequest *req);
280 : void DeleteAll();
281 : //Gets CN index from flow.
282 : static int GetCNIndex(const FlowEntry *flow);
283 : // Called just before entry is deleted. Used to implement cleanup operations
284 : virtual void FreeNotify(FlowMgmtKey *key, uint32_t gen_id);
285 :
286 : private:
287 : int index_;
288 : DISALLOW_COPY_AND_ASSIGN(BgpAsAServiceFlowMgmtTree);
289 : };
290 :
291 : #endif // __AGENT_PKT_FLOW_MGMT_TREE_H__
|