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  */
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>
12 
13 class FlowMgmtKeyNode;
14 class FlowMgmtEntry;
15 
17 
18 typedef std::map<FlowMgmtKey *, FlowMgmtKeyNode *, FlowMgmtKeyCmp> FlowMgmtKeyTree;
19 
20 class FlowMgmtTree {
21 public:
22  typedef std::map<FlowMgmtKey *, FlowMgmtEntry *, FlowMgmtKeyCmp> Tree;
24  virtual ~FlowMgmtTree() {
25  assert(tree_.size() == 0);
26  }
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 
61  Tree &tree() { return tree_; }
62  FlowMgmtManager *mgr() const { return mgr_; }
63  static bool AddFlowMgmtKey(FlowMgmtKeyTree *tree, FlowMgmtKey *key);
64 
65 protected:
66  bool TryDelete(FlowMgmtKey *key, FlowMgmtEntry *entry);
69 
70 private:
72 };
73 
75 // Object specific information below
77 class AclFlowMgmtTree : public FlowMgmtTree {
78 public:
80  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);
87  const MatchAclParamsList *acl_list);
89  FlowMgmtEntry *Allocate(const FlowMgmtKey *key);
90 
91 private:
93 };
94 
95 class VnFlowMgmtTree : public FlowMgmtTree {
96 public:
98  virtual ~VnFlowMgmtTree() {}
99 
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_;
114 };
115 
117 public:
120 
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_;
133 };
134 
135 class NhFlowMgmtTree : public FlowMgmtTree {
136 public:
138  virtual ~NhFlowMgmtTree() {}
139 
141  FlowMgmtEntry *Allocate(const FlowMgmtKey *key);
142 
143 private:
145 };
146 
148 public:
150  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);
160 };
161 
163 public:
166 
169 
170  void ExtractKeys(FlowEntry *flow, FlowMgmtKeyTree *tree, uint32_t vrf,
171  const IpAddress &ip, uint8_t plen);
173  const IpAddress &ip, const FlowRouteRefMap *rt_list);
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 
182  if (key->plen_ == 0)
183  return NULL;
184  return lpm_tree_.LPMFind(key);
185  }
186 
188  InetRouteFlowMgmtKey *rt_key =
189  static_cast<InetRouteFlowMgmtKey *>(key->Clone());
190  if (lpm_tree_.Insert(rt_key) == false)
191  delete rt_key;
192  }
193 
195  InetRouteFlowMgmtKey *rt_key = lpm_tree_.Find(key);
196  if (rt_key != NULL) {
197  lpm_tree_.Remove(rt_key);
198  delete rt_key;
199  }
200  }
201  bool RecomputeCoveringRoute(InetRouteFlowMgmtKey *covering_route,
202  InetRouteFlowMgmtKey *key);
203  bool RouteNHChangeEvent(const FlowMgmtRequest *req, FlowMgmtKey *key);
204 
205 private:
208 };
209 
211 public:
215  FlowMgmtEntry *Allocate(const FlowMgmtKey *key);
216  bool HasVrfFlows(uint32_t vrf_id, Agent::RouteTableType type);
217 
218 private:
220 };
221 
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
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;
251  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);
260 
261 private:
264 };
265 
267 public:
268  static const int kInvalidCnIndex = -1;
270  FlowMgmtTree(mgr), index_(index) {}
272 
274  FlowMgmtEntry *Allocate(const FlowMgmtKey *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_;
289 };
290 
291 #endif // __AGENT_PKT_FLOW_MGMT_TREE_H__
boost::asio::ip::address IpAddress
Definition: address.h:13
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:360
RouteTableType
Definition: agent.h:417
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:107
bool Remove(D *data)
Definition: patricia.h:95
bool Insert(D *data)
Definition: patricia.h:91
D * Find(const D *data)
Definition: patricia.h:99
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:151
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:89
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:220
std::map< FlowMgmtKey *, FlowMgmtKeyNode *, FlowMgmtKeyCmp > FlowMgmtKeyTree
uint8_t type
Definition: load_balance.h:2
map< int, int > FlowRouteRefMap
Definition: pkt_flow_info.h:16