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-11-09 02:10:49 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             :  * 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>
      12             : #include <pkt/flow_mgmt/flow_mgmt_key.h>
      13             : 
      14             : class FlowMgmtKeyNode;
      15             : class FlowMgmtEntry;
      16             : 
      17             : class BgpAsAServiceFlowMgmtRequest;
      18             : 
      19             : typedef std::map<FlowMgmtKey *, FlowMgmtKeyNode *, FlowMgmtKeyCmp> FlowMgmtKeyTree;
      20             : 
      21             : class FlowMgmtTree {
      22             : public:
      23             :     typedef std::map<FlowMgmtKey *, FlowMgmtEntry *, FlowMgmtKeyCmp> Tree;
      24          20 :     FlowMgmtTree(FlowMgmtManager *mgr) : mgr_(mgr) { }
      25          20 :     virtual ~FlowMgmtTree() {
      26          20 :         assert(tree_.size() == 0);
      27          20 :     }
      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             : 
      59             :     FlowMgmtEntry *Locate(FlowMgmtKey *key);
      60             :     FlowMgmtEntry *Find(FlowMgmtKey *key);
      61             :     FlowMgmtKey *LowerBound(FlowMgmtKey *key);
      62           0 :     Tree &tree() { return tree_; }
      63         296 :     FlowMgmtManager *mgr() const { return mgr_; }
      64             :     static bool AddFlowMgmtKey(FlowMgmtKeyTree *tree, FlowMgmtKey *key);
      65             : 
      66             : protected:
      67             :     bool TryDelete(FlowMgmtKey *key, FlowMgmtEntry *entry);
      68             :     Tree tree_;
      69             :     FlowMgmtManager *mgr_;
      70             : 
      71             : private:
      72             :     DISALLOW_COPY_AND_ASSIGN(FlowMgmtTree);
      73             : };
      74             : 
      75             : ////////////////////////////////////////////////////////////////////////////
      76             : // Object specific information below
      77             : ////////////////////////////////////////////////////////////////////////////
      78             : class AclFlowMgmtTree : public FlowMgmtTree {
      79             : public:
      80           2 :     AclFlowMgmtTree(FlowMgmtManager *mgr) : FlowMgmtTree(mgr) { }
      81           2 :     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);
      87             :     void ExtractKeys(FlowEntry *flow, FlowMgmtKeyTree *tree,
      88             :                      const MatchAclParamsList *acl_list);
      89             :     void ExtractKeys(FlowEntry *flow, FlowMgmtKeyTree *tree);
      90             :     FlowMgmtEntry *Allocate(const FlowMgmtKey *key);
      91             : 
      92             : private:
      93             :     DISALLOW_COPY_AND_ASSIGN(AclFlowMgmtTree);
      94             : };
      95             : 
      96             : class VnFlowMgmtTree : public FlowMgmtTree {
      97             : public:
      98           2 :     VnFlowMgmtTree(FlowMgmtManager *mgr) : FlowMgmtTree(mgr) {}
      99           2 :     virtual ~VnFlowMgmtTree() {}
     100             : 
     101             :     void ExtractKeys(FlowEntry *flow, FlowMgmtKeyTree *tree);
     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_;
     114             :     DISALLOW_COPY_AND_ASSIGN(VnFlowMgmtTree);
     115             : };
     116             : 
     117             : class InterfaceFlowMgmtTree : public FlowMgmtTree {
     118             : public:
     119           2 :     InterfaceFlowMgmtTree(FlowMgmtManager *mgr) : FlowMgmtTree(mgr) {}
     120           2 :     virtual ~InterfaceFlowMgmtTree() {}
     121             : 
     122             :     void ExtractKeys(FlowEntry *flow, FlowMgmtKeyTree *tree);
     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_;
     133             :     DISALLOW_COPY_AND_ASSIGN(InterfaceFlowMgmtTree);
     134             : };
     135             : 
     136             : class NhFlowMgmtTree : public FlowMgmtTree {
     137             : public:
     138           2 :     NhFlowMgmtTree(FlowMgmtManager *mgr) : FlowMgmtTree(mgr) {}
     139           2 :     virtual ~NhFlowMgmtTree() {}
     140             : 
     141             :     void ExtractKeys(FlowEntry *flow, FlowMgmtKeyTree *tree);
     142             :     FlowMgmtEntry *Allocate(const FlowMgmtKey *key);
     143             : 
     144             : private:
     145             :     DISALLOW_COPY_AND_ASSIGN(NhFlowMgmtTree);
     146             : };
     147             : 
     148             : class RouteFlowMgmtTree : public FlowMgmtTree {
     149             : public:
     150           6 :     RouteFlowMgmtTree(FlowMgmtManager *mgr) : FlowMgmtTree(mgr) { }
     151           6 :     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);
     160             :     DISALLOW_COPY_AND_ASSIGN(RouteFlowMgmtTree);
     161             : };
     162             : 
     163             : class InetRouteFlowMgmtTree : public RouteFlowMgmtTree {
     164             : public:
     165             :      typedef Patricia::Tree<InetRouteFlowMgmtKey, &InetRouteFlowMgmtKey::node_,
     166             :              InetRouteFlowMgmtKey::KeyCmp> LpmTree;
     167             : 
     168           4 :     InetRouteFlowMgmtTree(FlowMgmtManager *mgr) : RouteFlowMgmtTree(mgr) { }
     169           4 :     virtual ~InetRouteFlowMgmtTree() { }
     170             : 
     171             :     void ExtractKeys(FlowEntry *flow, FlowMgmtKeyTree *tree, uint32_t vrf,
     172             :                      const IpAddress &ip, uint8_t plen);
     173             :     void ExtractKeys(FlowEntry *flow, FlowMgmtKeyTree *tree,
     174             :                      const IpAddress &ip, const FlowRouteRefMap *rt_list);
     175             :     void ExtractKeys(FlowEntry *flow, FlowMgmtKeyTree *tree);
     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             : 
     182        1887 :     InetRouteFlowMgmtKey *LPM(const InetRouteFlowMgmtKey *key) {
     183        1887 :         if (key->plen_ == 0)
     184           0 :             return NULL;
     185        1887 :         return lpm_tree_.LPMFind(key);
     186             :     }
     187             : 
     188        1911 :     void AddToLPMTree(InetRouteFlowMgmtKey *key) {
     189             :         InetRouteFlowMgmtKey *rt_key =
     190        1911 :             static_cast<InetRouteFlowMgmtKey *>(key->Clone());
     191        1911 :         if (lpm_tree_.Insert(rt_key) == false)
     192         975 :             delete rt_key;
     193        1911 :     }
     194             : 
     195         936 :     void DelFromLPMTree(InetRouteFlowMgmtKey *key) {
     196         936 :         InetRouteFlowMgmtKey *rt_key = lpm_tree_.Find(key);
     197         936 :         if (rt_key != NULL) {
     198         936 :             lpm_tree_.Remove(rt_key);
     199         936 :             delete rt_key;
     200             :         }
     201         936 :     }
     202             :    bool RecomputeCoveringRoute(InetRouteFlowMgmtKey *covering_route,
     203             :                                InetRouteFlowMgmtKey *key);
     204             :    bool RouteNHChangeEvent(const FlowMgmtRequest *req, FlowMgmtKey *key);
     205             : 
     206             : private:
     207             :     LpmTree lpm_tree_;
     208             :     DISALLOW_COPY_AND_ASSIGN(InetRouteFlowMgmtTree);
     209             : };
     210             : 
     211             : class BridgeRouteFlowMgmtTree : public RouteFlowMgmtTree {
     212             : public:
     213           2 :     BridgeRouteFlowMgmtTree(FlowMgmtManager *mgr) : RouteFlowMgmtTree(mgr) { }
     214           2 :     virtual ~BridgeRouteFlowMgmtTree() { }
     215             :     void ExtractKeys(FlowEntry *flow, FlowMgmtKeyTree *tree);
     216             :     FlowMgmtEntry *Allocate(const FlowMgmtKey *key);
     217             :     bool HasVrfFlows(uint32_t vrf_id, Agent::RouteTableType type);
     218             : 
     219             : private:
     220             :     DISALLOW_COPY_AND_ASSIGN(BridgeRouteFlowMgmtTree);
     221             : };
     222             : 
     223             : ////////////////////////////////////////////////////////////////////////////
     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
     244             : ////////////////////////////////////////////////////////////////////////////
     245             : class VrfFlowMgmtTree : public FlowMgmtTree {
     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;
     251           2 :     VrfFlowMgmtTree(FlowMgmtManager *mgr) : FlowMgmtTree(mgr) { }
     252           2 :     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);
     260             :     void ExtractKeys(FlowEntry *flow, FlowMgmtKeyTree *tree);
     261             : 
     262             : private:
     263             :     VrfIdMap id_map_;
     264             :     DISALLOW_COPY_AND_ASSIGN(VrfFlowMgmtTree);
     265             : };
     266             : 
     267             : class BgpAsAServiceFlowMgmtTree : public FlowMgmtTree {
     268             : public:
     269             :     static const int kInvalidCnIndex = -1;
     270           4 :     BgpAsAServiceFlowMgmtTree(FlowMgmtManager *mgr, int index) :
     271           4 :         FlowMgmtTree(mgr), index_(index) {}
     272           8 :     virtual ~BgpAsAServiceFlowMgmtTree() {}
     273             : 
     274             :     void ExtractKeys(FlowEntry *flow, FlowMgmtKeyTree *tree);
     275             :     FlowMgmtEntry *Allocate(const FlowMgmtKey *key);
     276             :     bool BgpAsAServiceHealthCheckUpdate(Agent *agent,
     277             :                                         BgpAsAServiceFlowMgmtKey &key,
     278             :                                         BgpAsAServiceFlowMgmtRequest *req);
     279             :     bool BgpAsAServiceDelete(BgpAsAServiceFlowMgmtKey &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_;
     289             :     DISALLOW_COPY_AND_ASSIGN(BgpAsAServiceFlowMgmtTree);
     290             : };
     291             : 
     292             : #endif // __AGENT_PKT_FLOW_MGMT_TREE_H__

Generated by: LCOV version 1.14