LCOV - code coverage report
Current view: top level - vnsw/agent/pkt/flow_mgmt - flow_mgmt_tree.h (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 38 40 95.0 %
Date: 2026-08-03 02:19:58 Functions: 25 35 71.4 %
Legend: Lines: hit not hit

          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__

Generated by: LCOV version 1.14