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