LCOV - code coverage report
Current view: top level - vnsw/agent/pkt/flow_mgmt - flow_mgmt_tree.cc (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 0 409 0.0 %
Date: 2026-10-05 02:12:29 Functions: 0 61 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2018 Juniper Networks, Inc. All rights reserved.
       3             :  */
       4             : 
       5             : #include <pkt/flow_mgmt/flow_mgmt_tree.h>
       6             : #include <pkt/flow_mgmt/flow_mgmt_key.h>
       7             : #include <pkt/flow_mgmt/flow_mgmt_entry.h>
       8             : #include <pkt/flow_mgmt/flow_mgmt_request.h>
       9             : #include <pkt/flow_mgmt.h>
      10             : 
      11           0 : FlowMgmtEntry *FlowMgmtTree::Find(FlowMgmtKey *key) {
      12           0 :     Tree::iterator it = tree_.find(key);
      13           0 :     if (it == tree_.end())
      14           0 :         return NULL;
      15             : 
      16           0 :     return it->second;
      17             : }
      18             : 
      19           0 : FlowMgmtEntry *FlowMgmtTree::Locate(FlowMgmtKey *key) {
      20           0 :     FlowMgmtEntry *entry = Find(key);
      21           0 :     if (entry == NULL) {
      22           0 :         entry = Allocate(key);
      23           0 :         InsertEntry(key->Clone(), entry);
      24             :     }
      25             : 
      26           0 :     return entry;
      27             : }
      28             : 
      29           0 : void FlowMgmtTree::InsertEntry(FlowMgmtKey *key, FlowMgmtEntry *entry) {
      30           0 :     tree_[key] = entry;
      31           0 : }
      32             : 
      33           0 : FlowMgmtKey *FlowMgmtTree::LowerBound(FlowMgmtKey *key) {
      34           0 :     Tree::iterator it = tree_.lower_bound(key);
      35           0 :     if (it == tree_.end())
      36           0 :         return NULL;
      37             : 
      38           0 :     return it->first;
      39             : }
      40             : 
      41           0 : bool FlowMgmtTree::TryDelete(FlowMgmtKey *key, FlowMgmtEntry *entry) {
      42           0 :     if (entry->CanDelete() == false)
      43           0 :         return false;
      44             : 
      45             :     // Send message only if we have seen DELETE message from FlowTable
      46           0 :     if (entry->oper_state() == FlowMgmtEntry::OPER_DEL_SEEN) {
      47           0 :         FreeNotify(key, entry->gen_id());
      48             :     }
      49             : 
      50           0 :     Tree::iterator it = tree_.find(key);
      51           0 :     assert(it != tree_.end());
      52           0 :     FlowMgmtKey *first = it->first;
      53           0 :     RemoveEntry(it);
      54           0 :     delete entry;
      55           0 :     delete first;
      56             : 
      57           0 :     return true;
      58             : }
      59             : 
      60           0 : void FlowMgmtTree::RemoveEntry(Tree::iterator it) {
      61           0 :     tree_.erase(it);
      62           0 : }
      63             : 
      64             : /////////////////////////////////////////////////////////////////////////////
      65             : // Generic Event handler on tree for add/delete of a flow
      66             : /////////////////////////////////////////////////////////////////////////////
      67           0 : bool FlowMgmtTree::AddFlowMgmtKey(FlowMgmtKeyTree *tree, FlowMgmtKey *key) {
      68           0 :     FlowMgmtKeyNode *node = new FlowMgmtKeyNode();
      69           0 :     std::pair<FlowMgmtKeyTree::iterator, bool> ret;
      70           0 :     ret = tree->insert(make_pair(key, node));
      71           0 :     if (ret.second == false) {
      72           0 :         delete key;
      73           0 :         delete node;
      74             :     }
      75           0 :     return ret.second;
      76             : }
      77             : 
      78             : // Adds Flow to a FlowMgmtEntry defined by key. Does not allocate FlowMgmtEntry
      79             : // if its not already present
      80           0 : bool FlowMgmtTree::Add(FlowMgmtKey *key, FlowEntry *flow,
      81             :                        FlowMgmtKeyNode *node) {
      82           0 :     FlowMgmtEntry *entry = Locate(key);
      83           0 :     if (entry == NULL) {
      84           0 :         return false;
      85             :     }
      86             : 
      87           0 :     return entry->Add(flow, node);
      88             : }
      89             : 
      90           0 : bool FlowMgmtTree::Delete(FlowMgmtKey *key, FlowEntry *flow,
      91             :                           FlowMgmtKeyNode *node) {
      92           0 :     Tree::iterator it = tree_.find(key);
      93           0 :     if (it == tree_.end()) {
      94           0 :         return false;
      95             :     }
      96             : 
      97           0 :     FlowMgmtEntry *entry = it->second;
      98           0 :     bool ret = entry->Delete(flow, node);
      99             : 
     100           0 :     TryDelete(it->first, entry);
     101           0 :     return ret;
     102             : }
     103             : 
     104             : /////////////////////////////////////////////////////////////////////////////
     105             : // Event handler for add/delete/change of an object
     106             : /////////////////////////////////////////////////////////////////////////////
     107             : 
     108             : // Send DBEntry Free message to DB Client module
     109           0 : void FlowMgmtTree::FreeNotify(FlowMgmtKey *key, uint32_t gen_id) {
     110           0 :     assert(key->db_entry() != NULL);
     111           0 :     FlowEvent::Event event = key->FreeDBEntryEvent();
     112           0 :     if (event == FlowEvent::INVALID)
     113           0 :         return;
     114           0 :     mgr_->FreeDBEntryEvent(event, key, gen_id);
     115             : }
     116             : 
     117             : // An object is added/updated. Enqueue REVALUATE for flows dependent on it
     118           0 : bool FlowMgmtTree::OperEntryAdd(const FlowMgmtRequest *req, FlowMgmtKey *key) {
     119           0 :     FlowMgmtEntry *entry = Locate(key);
     120           0 :     entry->OperEntryAdd(mgr_, req, key);
     121           0 :     return true;
     122             : }
     123             : 
     124           0 : bool FlowMgmtTree::OperEntryChange(const FlowMgmtRequest *req,
     125             :                                    FlowMgmtKey *key) {
     126           0 :     FlowMgmtEntry *entry = Find(key);
     127           0 :     if (entry) {
     128           0 :         entry->OperEntryChange(mgr_, req, key);
     129             :     }
     130           0 :     return true;
     131             : }
     132             : 
     133             : // Send DELETE Entry message to FlowTable module
     134           0 : bool FlowMgmtTree::OperEntryDelete(const FlowMgmtRequest *req,
     135             :                                    FlowMgmtKey *key) {
     136           0 :     FlowMgmtEntry *entry = Find(key);
     137           0 :     if (entry == NULL) {
     138           0 :         FreeNotify(key, req->gen_id());
     139           0 :         return true;
     140             :     }
     141             : 
     142           0 :     entry->OperEntryDelete(mgr_, req, key);
     143           0 :     return TryDelete(key, entry);
     144             : }
     145             : 
     146           0 : bool FlowMgmtTree::RetryDelete(FlowMgmtKey *key) {
     147           0 :     FlowMgmtEntry *entry = Find(key);
     148           0 :     if (entry == NULL) {
     149           0 :         return true;
     150             :     }
     151             : 
     152           0 :     return TryDelete(key, entry);
     153             : }
     154             : 
     155           0 : void BgpAsAServiceFlowMgmtTree::FreeNotify(FlowMgmtKey *key, uint32_t gen_id) {
     156           0 :     assert(key->db_entry() == NULL);
     157           0 : }
     158             : 
     159           0 : void BgpAsAServiceFlowMgmtTree::ExtractKeys(FlowEntry *flow,
     160             :                                             FlowMgmtKeyTree *tree) {
     161           0 :     if (flow->is_flags_set(FlowEntry::BgpRouterService) == false)
     162           0 :         return;
     163             :     const VmInterface *vm_intf =
     164           0 :         dynamic_cast<const VmInterface *>(flow->intf_entry());
     165           0 :     if (!vm_intf || (flow->bgp_as_a_service_sport() == 0))
     166           0 :         return;
     167             : 
     168             :     BgpAsAServiceFlowMgmtKey *key =
     169           0 :         new BgpAsAServiceFlowMgmtKey(vm_intf->GetUuid(),
     170           0 :                                  flow->bgp_as_a_service_sport(),
     171           0 :                                  index_, NULL, NULL);
     172           0 :     AddFlowMgmtKey(tree, key);
     173             : }
     174             : 
     175           0 : FlowMgmtEntry *BgpAsAServiceFlowMgmtTree::Allocate(const FlowMgmtKey *key) {
     176           0 :     return new BgpAsAServiceFlowMgmtEntry();
     177             : }
     178             : 
     179             : // Update health check on the BgpAsAService entry
     180           0 : bool BgpAsAServiceFlowMgmtTree::BgpAsAServiceHealthCheckUpdate
     181             :     (Agent *agent, BgpAsAServiceFlowMgmtKey &key,
     182             :      BgpAsAServiceFlowMgmtRequest *req) {
     183           0 :     FlowMgmtEntry *entry = Find(&key);
     184           0 :     if (entry == NULL) {
     185           0 :         return true;
     186             :     }
     187             : 
     188           0 :     BgpAsAServiceFlowMgmtEntry *bgpaas_entry =
     189             :         static_cast<BgpAsAServiceFlowMgmtEntry *>(entry);
     190           0 :     return bgpaas_entry->HealthCheckUpdate(agent, mgr_, key, req);
     191             : }
     192             : 
     193           0 : bool BgpAsAServiceFlowMgmtTree::BgpAsAServiceDelete
     194             : (BgpAsAServiceFlowMgmtKey &key, const FlowMgmtRequest *req) {
     195           0 :     FlowMgmtEntry *entry = Find(&key);
     196           0 :     if (entry == NULL) {
     197           0 :         return true;
     198             :     }
     199             : 
     200           0 :     entry->NonOperEntryDelete(mgr_, req, &key);
     201           0 :     return TryDelete(&key, entry);
     202             : }
     203             : 
     204           0 : void BgpAsAServiceFlowMgmtTree::DeleteAll() {
     205           0 :     Tree::iterator it = tree_.begin();
     206           0 :     while (it != tree_.end()) {
     207             :         BgpAsAServiceFlowMgmtKey *key =
     208           0 :             static_cast<BgpAsAServiceFlowMgmtKey *>(it->first);
     209           0 :         mgr_->BgpAsAServiceNotify(key->uuid(), key->source_port());
     210           0 :         it++;
     211             :     }
     212           0 : }
     213             : 
     214           0 : int BgpAsAServiceFlowMgmtTree::GetCNIndex(const FlowEntry *flow) {
     215           0 :     IpAddress dest_ip = IpAddress();
     216           0 :     if (flow->is_flags_set(FlowEntry::ReverseFlow)) {
     217           0 :         dest_ip = flow->key().src_addr;
     218             :     } else {
     219             :         //No reverse flow means no CN to map to so dont add flow key.
     220           0 :         if (flow->reverse_flow_entry() == NULL)
     221           0 :             return BgpAsAServiceFlowMgmtTree::kInvalidCnIndex;
     222           0 :         dest_ip = flow->reverse_flow_entry()->key().src_addr;
     223             :     }
     224           0 :     for (uint8_t count = 0; count < MAX_XMPP_SERVERS; count++) {
     225           0 :         if (flow->flow_table()->agent()->controller_ifmap_xmpp_server(count) ==
     226           0 :             dest_ip.to_string()) {
     227           0 :             return count;
     228             :         }
     229             :     }
     230           0 :     return BgpAsAServiceFlowMgmtTree::kInvalidCnIndex;
     231             : }
     232             : 
     233             : /////////////////////////////////////////////////////////////////////////////
     234             : // Acl Flow Management
     235             : /////////////////////////////////////////////////////////////////////////////
     236           0 : void AclFlowMgmtTree::ExtractKeys(FlowEntry *flow, FlowMgmtKeyTree *tree,
     237             :                                   const MatchAclParamsList *acl_list) {
     238           0 :     std::list<MatchAclParams>::const_iterator it;
     239           0 :     for (it = acl_list->begin(); it != acl_list->end(); it++) {
     240           0 :         AclFlowMgmtKey *key = new AclFlowMgmtKey(it->acl.get(),
     241           0 :                                                  &it->ace_id_list);
     242           0 :         AddFlowMgmtKey(tree, key);
     243             :     }
     244           0 : }
     245             : 
     246           0 : void AclFlowMgmtTree::ExtractKeys(FlowEntry *flow, FlowMgmtKeyTree *tree) {
     247           0 :     ExtractKeys(flow, tree, &flow->match_p().m_acl_l);
     248           0 :     ExtractKeys(flow, tree, &flow->match_p().m_out_acl_l);
     249           0 :     ExtractKeys(flow, tree, &flow->match_p().sg_policy.m_acl_l);
     250           0 :     ExtractKeys(flow, tree, &flow->match_p().sg_policy.m_out_acl_l);
     251           0 :     ExtractKeys(flow, tree, &flow->match_p().sg_policy.m_reverse_acl_l);
     252           0 :     ExtractKeys(flow, tree, &flow->match_p().sg_policy.m_reverse_out_acl_l);
     253           0 :     ExtractKeys(flow, tree, &flow->match_p().m_mirror_acl_l);
     254           0 :     ExtractKeys(flow, tree, &flow->match_p().m_out_mirror_acl_l);
     255           0 :     ExtractKeys(flow, tree, &flow->match_p().m_vrf_assign_acl_l);
     256           0 :     ExtractKeys(flow, tree, &flow->match_p().aps_policy.m_acl_l);
     257           0 :     ExtractKeys(flow, tree, &flow->match_p().aps_policy.m_out_acl_l);
     258           0 :     ExtractKeys(flow, tree, &flow->match_p().fwaas_policy.m_acl_l);
     259           0 :     ExtractKeys(flow, tree, &flow->match_p().fwaas_policy.m_out_acl_l);
     260           0 : }
     261             : 
     262           0 : FlowMgmtEntry *AclFlowMgmtTree::Allocate(const FlowMgmtKey *key) {
     263           0 :     return new AclFlowMgmtEntry();
     264             : }
     265             : 
     266           0 : bool AclFlowMgmtTree::Add(FlowMgmtKey *key, FlowEntry *flow,
     267             :                           FlowMgmtKey *old_key, FlowMgmtKeyNode *node) {
     268           0 :     AclFlowMgmtEntry *entry = static_cast<AclFlowMgmtEntry *>(Locate(key));
     269           0 :     if (entry == NULL) {
     270           0 :         return false;
     271             :     }
     272             : 
     273           0 :     AclFlowMgmtKey *acl_key = static_cast<AclFlowMgmtKey *>(key);
     274           0 :     const AclEntryIDList *old_ace_id_list = NULL;
     275           0 :     if (old_key) {
     276           0 :         AclFlowMgmtKey *old_acl_key = static_cast<AclFlowMgmtKey *>(old_key);
     277           0 :         old_ace_id_list = old_acl_key->ace_id_list();
     278             :     }
     279           0 :     return entry->Add(acl_key->ace_id_list(), flow, old_ace_id_list, node);
     280             : }
     281             : 
     282           0 : bool AclFlowMgmtTree::Delete(FlowMgmtKey *key, FlowEntry *flow,
     283             :                              FlowMgmtKeyNode *node) {
     284           0 :     Tree::iterator it = tree_.find(key);
     285           0 :     if (it == tree_.end()) {
     286           0 :         return false;
     287             :     }
     288             : 
     289           0 :     AclFlowMgmtKey *acl_key = static_cast<AclFlowMgmtKey *>(key);
     290           0 :     AclFlowMgmtEntry *entry = static_cast<AclFlowMgmtEntry *>(it->second);
     291           0 :     bool ret = entry->Delete(acl_key->ace_id_list(), flow, node);
     292             : 
     293           0 :     TryDelete(it->first, entry);
     294           0 :     return ret;
     295             : }
     296             : 
     297             : /////////////////////////////////////////////////////////////////////////////
     298             : // VN Flow Management
     299             : /////////////////////////////////////////////////////////////////////////////
     300           0 : void VnFlowMgmtTree::ExtractKeys(FlowEntry *flow, FlowMgmtKeyTree *tree) {
     301           0 :     if (flow->vn_entry() == NULL)
     302           0 :         return;
     303           0 :     VnFlowMgmtKey *key = new VnFlowMgmtKey(flow->vn_entry());
     304           0 :     AddFlowMgmtKey(tree, key);
     305             : }
     306             : 
     307           0 : FlowMgmtEntry *VnFlowMgmtTree::Allocate(const FlowMgmtKey *key) {
     308           0 :     return new VnFlowMgmtEntry();
     309             : }
     310             : 
     311           0 : void VnFlowMgmtTree::InsertEntry(FlowMgmtKey *key, FlowMgmtEntry *entry) {
     312           0 :     std::scoped_lock mutex(mutex_);
     313           0 :     FlowMgmtTree::InsertEntry(key, entry);
     314           0 : }
     315             : 
     316           0 : void VnFlowMgmtTree::RemoveEntry(Tree::iterator it) {
     317           0 :     std::scoped_lock mutex(mutex_);
     318           0 :     FlowMgmtTree::RemoveEntry(it);
     319           0 : }
     320             : 
     321           0 : void VnFlowMgmtTree::VnFlowCounters(const VnEntry *vn,
     322             :                                     uint32_t *ingress_flow_count,
     323             :                                     uint32_t *egress_flow_count) {
     324           0 :     VnFlowMgmtKey key(vn);
     325           0 :     std::scoped_lock mutex(mutex_);
     326           0 :     VnFlowMgmtEntry *entry = static_cast<VnFlowMgmtEntry *>(Find(&key));
     327           0 :     if (entry) {
     328           0 :         *ingress_flow_count += entry->ingress_flow_count();
     329           0 :         *egress_flow_count += entry->egress_flow_count();
     330             :     }
     331           0 : }
     332             : 
     333             : /////////////////////////////////////////////////////////////////////////////
     334             : // Interface Flow Management
     335             : /////////////////////////////////////////////////////////////////////////////
     336           0 : void InterfaceFlowMgmtTree::InsertEntry(FlowMgmtKey *key, FlowMgmtEntry *entry){
     337           0 :     std::scoped_lock mutex(mutex_);
     338           0 :     FlowMgmtTree::InsertEntry(key, entry);
     339           0 : }
     340             : 
     341           0 : void InterfaceFlowMgmtTree::RemoveEntry(Tree::iterator it) {
     342           0 :     std::scoped_lock mutex(mutex_);
     343           0 :     FlowMgmtTree::RemoveEntry(it);
     344           0 : }
     345             : 
     346           0 : void InterfaceFlowMgmtTree::InterfaceFlowCount(const Interface *itf,
     347             :                                                uint64_t *created,
     348             :                                                uint64_t *aged,
     349             :                                                uint32_t *active_flows) {
     350           0 :     InterfaceFlowMgmtKey key(itf);
     351           0 :     std::scoped_lock mutex(mutex_);
     352             :     InterfaceFlowMgmtEntry *entry = static_cast<InterfaceFlowMgmtEntry *>
     353           0 :         (Find(&key));
     354           0 :     if (entry) {
     355           0 :         *created += entry->flow_created();
     356           0 :         *aged += entry->flow_aged();
     357           0 :         *active_flows += entry->Size();
     358             :     }
     359           0 : }
     360             : 
     361           0 : void InterfaceFlowMgmtTree::ExtractKeys(FlowEntry *flow,
     362             :                                         FlowMgmtKeyTree *tree) {
     363           0 :     if (flow->intf_entry() == NULL)
     364           0 :         return;
     365             :     InterfaceFlowMgmtKey *key =
     366           0 :         new InterfaceFlowMgmtKey(flow->intf_entry());
     367           0 :     AddFlowMgmtKey(tree, key);
     368             : }
     369             : 
     370           0 : FlowMgmtEntry *InterfaceFlowMgmtTree::Allocate(const FlowMgmtKey *key) {
     371           0 :     return new InterfaceFlowMgmtEntry();
     372             : }
     373             : 
     374             : /////////////////////////////////////////////////////////////////////////////
     375             : // Nh Flow Management
     376             : /////////////////////////////////////////////////////////////////////////////
     377           0 : void NhFlowMgmtTree::ExtractKeys(FlowEntry *flow, FlowMgmtKeyTree *tree) {
     378           0 :     if (flow->rpf_nh() == NULL)
     379           0 :         return;
     380           0 :     NhFlowMgmtKey *key = new NhFlowMgmtKey(flow->rpf_nh());
     381           0 :     AddFlowMgmtKey(tree, key);
     382             : }
     383             : 
     384           0 : FlowMgmtEntry *NhFlowMgmtTree::Allocate(const FlowMgmtKey *key) {
     385           0 :     return new NhFlowMgmtEntry();
     386             : }
     387             : 
     388             : /////////////////////////////////////////////////////////////////////////////
     389             : // Route Flow Management
     390             : /////////////////////////////////////////////////////////////////////////////
     391           0 : bool RouteFlowMgmtTree::Delete(FlowMgmtKey *key, FlowEntry *flow,
     392             :                                FlowMgmtKeyNode *node) {
     393           0 :     bool ret = FlowMgmtTree::Delete(key, flow, node);
     394           0 :     RouteFlowMgmtKey *route_key = static_cast<RouteFlowMgmtKey *>(key);
     395           0 :     mgr_->RetryVrfDelete(route_key->vrf_id());
     396           0 :     return ret;
     397             : }
     398             : 
     399           0 : void RouteFlowMgmtTree::SetDBEntry(const FlowMgmtRequest *req,
     400             :                                    FlowMgmtKey *key) {
     401           0 :     Tree::iterator it = tree_.find(key);
     402           0 :     if (it == tree_.end()) {
     403           0 :         return;
     404             :     }
     405             : 
     406           0 :     if (req->db_entry() == NULL) {
     407           0 :         return;
     408             :     }
     409             : 
     410           0 :     if (it->first->db_entry()) {
     411           0 :         assert(it->first->db_entry() == req->db_entry());
     412           0 :         return;
     413             :     }
     414           0 :     it->first->set_db_entry(req->db_entry());
     415           0 :     return;
     416             : }
     417             : 
     418           0 : bool RouteFlowMgmtTree::OperEntryDelete(const FlowMgmtRequest *req,
     419             :                                         FlowMgmtKey *key) {
     420             :     // Set the db_entry if it was not set earlier. It is needed to send the
     421             :     // FreeDBState message
     422           0 :     SetDBEntry(req, key);
     423           0 :     bool ret = FlowMgmtTree::OperEntryDelete(req, key);
     424           0 :     RouteFlowMgmtKey *route_key = static_cast<RouteFlowMgmtKey *>(key);
     425           0 :     mgr_->RetryVrfDelete(route_key->vrf_id());
     426           0 :     return ret;
     427             : }
     428             : 
     429           0 : bool RouteFlowMgmtTree::OperEntryAdd(const FlowMgmtRequest *req,
     430             :                                      FlowMgmtKey *key) {
     431           0 :     bool ret = FlowMgmtTree::OperEntryAdd(req, key);
     432           0 :     if (req->db_entry() == NULL)
     433           0 :         return ret;
     434             : 
     435             :     // Set the DBEntry in the flow-mgmt-entry
     436           0 :     SetDBEntry(req, key);
     437           0 :     return ret;
     438             : }
     439             : 
     440             : /////////////////////////////////////////////////////////////////////////////
     441             : // Inet Route Flow Management
     442             : /////////////////////////////////////////////////////////////////////////////
     443           0 : void InetRouteFlowMgmtTree::ExtractKeys(FlowEntry *flow, FlowMgmtKeyTree *tree,
     444             :                                         uint32_t vrf, const IpAddress &ip,
     445             :                                         uint8_t plen) {
     446             :     // We do not support renewal of VRF, so skip flow if VRF is deleted
     447           0 :     VrfEntry *vrfp = mgr_->agent()->vrf_table()->FindVrfFromId(vrf);
     448           0 :     if (vrfp == NULL) {
     449           0 :         return;
     450             :     }
     451             : 
     452           0 :     InetRouteFlowMgmtKey *key = NULL;
     453             :     /*
     454             :      * For L2 flows, plen is found using LPMFind
     455             :      * when route is not found plen is set to -1(255)
     456             :      * in that case key should not be added
     457             :      */ 
     458           0 :     if (flow->l3_flow() || (plen != 255)) {
     459           0 :         if (ip.is_v4()) {
     460           0 :             Ip4Address ip4 = Address::GetIp4SubnetAddress(ip.to_v4(), plen);
     461           0 :             key = new InetRouteFlowMgmtKey(vrf, ip4, plen);
     462             :         } else {
     463           0 :             Ip6Address ip6 = Address::GetIp6SubnetAddress(ip.to_v6(), plen);
     464           0 :             key = new InetRouteFlowMgmtKey(vrf, ip6, plen);
     465             :         }
     466             :     }
     467             : 
     468           0 :     if (key) {
     469           0 :         AddFlowMgmtKey(tree, key);
     470             :     }
     471             : }
     472             : 
     473           0 : void InetRouteFlowMgmtTree::ExtractKeys(FlowEntry *flow, FlowMgmtKeyTree *tree,
     474             :                                         const IpAddress &ip,
     475             :                                         const FlowRouteRefMap *rt_list) {
     476           0 :     FlowRouteRefMap::const_iterator it;
     477           0 :     for (it = rt_list->begin(); it != rt_list->end(); it++) {
     478           0 :         ExtractKeys(flow, tree, it->first, ip, it->second);
     479             :     }
     480           0 : }
     481             : 
     482           0 : void InetRouteFlowMgmtTree::ExtractKeys(FlowEntry *flow,
     483             :                                         FlowMgmtKeyTree *tree) {
     484             : 
     485           0 :     if (flow->l3_flow() == false) {
     486             :         // For l2-flows Track INET route for RPF only
     487           0 :         if (flow->data().rpf_vrf != VrfEntry::kInvalidIndex) {
     488           0 :             ExtractKeys(flow, tree, flow->data().rpf_vrf,
     489           0 :                         flow->key().src_addr, flow->data().rpf_plen);
     490             :         }
     491           0 :         return;
     492             :     }
     493             : 
     494           0 :     if (flow->data().flow_source_vrf != VrfEntry::kInvalidIndex) {
     495           0 :         ExtractKeys(flow, tree, flow->data().flow_source_vrf,
     496           0 :                     flow->key().src_addr, flow->data().source_plen);
     497             :     }
     498             : 
     499           0 :     if (flow->data().acl_assigned_vrf_index_ != VrfEntry::kInvalidIndex) {
     500           0 :         ExtractKeys(flow, tree, flow->data().acl_assigned_vrf_index_,
     501           0 :                     flow->key().src_addr, flow->data().source_plen);
     502           0 :         ExtractKeys(flow, tree, flow->data().acl_assigned_vrf_index_,
     503           0 :                     flow->key().dst_addr, flow->data().dest_plen);
     504             :     }
     505             : 
     506           0 :     ExtractKeys(flow, tree, flow->key().src_addr,
     507           0 :                 &flow->data().flow_source_plen_map);
     508             : 
     509           0 :     if (flow->data().flow_dest_vrf != VrfEntry::kInvalidIndex) {
     510           0 :         ExtractKeys(flow, tree, flow->data().flow_dest_vrf,
     511           0 :                     flow->key().dst_addr, flow->data().dest_plen);
     512             :     }
     513           0 :     ExtractKeys(flow, tree, flow->key().dst_addr,
     514           0 :                 &flow->data().flow_dest_plen_map);
     515             : 
     516           0 :     if (flow->data().src_policy_vrf != VrfEntry::kInvalidIndex) {
     517           0 :         ExtractKeys(flow, tree, flow->data().src_policy_vrf,
     518           0 :                     flow->key().src_addr, flow->data().src_policy_plen);
     519             :     }
     520             : 
     521           0 :     if (flow->data().dst_policy_vrf != VrfEntry::kInvalidIndex) {
     522           0 :         ExtractKeys(flow, tree, flow->data().dst_policy_vrf,
     523           0 :                     flow->key().dst_addr, flow->data().dst_policy_plen);
     524             :     }
     525             : 
     526             : }
     527             : 
     528           0 : FlowMgmtEntry *InetRouteFlowMgmtTree::Allocate(const FlowMgmtKey *key) {
     529           0 :     return new InetRouteFlowMgmtEntry();
     530             : }
     531             : 
     532           0 : bool InetRouteFlowMgmtTree::HasVrfFlows(uint32_t vrf,
     533             :                                         Agent::RouteTableType type) {
     534           0 :     InetRouteFlowMgmtKey *next_key = NULL;
     535             : 
     536           0 :     if (type == Agent::INET4_UNICAST) {
     537           0 :         InetRouteFlowMgmtKey key(vrf, Ip4Address(0), 0);
     538           0 :         next_key = static_cast<InetRouteFlowMgmtKey *>(LowerBound(&key));
     539           0 :     } else if (type == Agent::INET6_UNICAST) {
     540           0 :         InetRouteFlowMgmtKey key(vrf, Ip6Address(), 0);
     541           0 :         next_key = static_cast<InetRouteFlowMgmtKey *>(LowerBound(&key));
     542           0 :     } else {
     543           0 :         return false;
     544             :     }
     545             : 
     546           0 :     if (next_key == NULL)
     547           0 :         return false;
     548             : 
     549           0 :     if (next_key->vrf_id() != vrf)
     550           0 :         return false;
     551             : 
     552           0 :     return true;
     553             : }
     554             : 
     555           0 : bool InetRouteFlowMgmtTree::OperEntryAdd(const FlowMgmtRequest *req,
     556             :                                          FlowMgmtKey *key) {
     557           0 :     bool ret = RouteFlowMgmtTree::OperEntryAdd(req, key);
     558             : 
     559             :     // A new route is added. This new route can be a longer prefix route for
     560             :     // flows using lower prefix-len (covering routes). So, do a LPM match to
     561             :     // find the covering route and trigger flow re-compute for flows on the
     562             :     // covering route
     563           0 :     InetRouteFlowMgmtKey *rt_key = static_cast<InetRouteFlowMgmtKey *>(key);
     564           0 :     AddToLPMTree(rt_key);
     565           0 :     if (rt_key->plen_ > 0) {
     566           0 :         InetRouteFlowMgmtKey lpm_key(rt_key->vrf_id_, rt_key->ip_,
     567           0 :                                      rt_key->plen_ - 1);
     568           0 :         InetRouteFlowMgmtKey *covering_route = LPM(&lpm_key);
     569           0 :         if (covering_route != NULL) {
     570           0 :             ret = RecomputeCoveringRoute(covering_route, rt_key);
     571             :         }
     572           0 :         rt_key->plen_ += 1;
     573           0 :     }
     574             : 
     575           0 :     return ret;
     576             : }
     577             : 
     578           0 : bool InetRouteFlowMgmtTree::RecomputeCoveringRoute
     579             : (InetRouteFlowMgmtKey *covering_route, InetRouteFlowMgmtKey *key) {
     580           0 :     InetRouteFlowMgmtEntry *entry = dynamic_cast<InetRouteFlowMgmtEntry *>
     581           0 :                                     (Find(covering_route));
     582           0 :     if (entry == NULL) {
     583           0 :         return true;
     584             :     }
     585             : 
     586           0 :     return entry->RecomputeCoveringRouteEntry(mgr_, covering_route, key);
     587             : }
     588             : 
     589           0 : bool InetRouteFlowMgmtTree::OperEntryDelete(const FlowMgmtRequest *req,
     590             :                                             FlowMgmtKey *key) {
     591           0 :     InetRouteFlowMgmtKey *rt_key = static_cast<InetRouteFlowMgmtKey *>(key);
     592           0 :     DelFromLPMTree(rt_key);
     593           0 :     return RouteFlowMgmtTree::OperEntryDelete(req, key);
     594             : }
     595             : 
     596           0 : bool InetRouteFlowMgmtTree::RouteNHChangeEvent(const FlowMgmtRequest *req,
     597             :                                                FlowMgmtKey *key) {
     598             :     InetRouteFlowMgmtEntry *entry = static_cast<InetRouteFlowMgmtEntry*>
     599           0 :         (Find(key));
     600           0 :     if (entry == NULL) {
     601           0 :         return true;
     602             :     }
     603             : 
     604           0 :     return entry->HandleNhChange(mgr_, req, key);
     605             : }
     606             : 
     607             : /////////////////////////////////////////////////////////////////////////////
     608             : // Bridge Route Flow Management
     609             : /////////////////////////////////////////////////////////////////////////////
     610           0 : void BridgeRouteFlowMgmtTree::ExtractKeys(FlowEntry *flow,
     611             :                                           FlowMgmtKeyTree *tree) {
     612           0 :     if (flow->l3_flow() == true)
     613           0 :         return;
     614             : 
     615           0 :     VrfTable *table = mgr_->agent()->vrf_table();
     616           0 :     uint32_t vrf = flow->data().flow_source_vrf;
     617           0 :     if (vrf != VrfEntry::kInvalidIndex && table->FindVrfFromId(vrf) != NULL) {
     618             :         BridgeRouteFlowMgmtKey *key =
     619           0 :             new BridgeRouteFlowMgmtKey(vrf, flow->data().smac);
     620           0 :         AddFlowMgmtKey(tree, key);
     621             :     }
     622             : 
     623           0 :     vrf = flow->data().flow_dest_vrf;
     624           0 :     if (vrf != VrfEntry::kInvalidIndex && table->FindVrfFromId(vrf) != NULL) {
     625             :         BridgeRouteFlowMgmtKey *key =
     626           0 :             new BridgeRouteFlowMgmtKey(vrf, flow->data().smac);
     627           0 :         AddFlowMgmtKey(tree, key);
     628             :     }
     629             : }
     630             : 
     631           0 : FlowMgmtEntry *BridgeRouteFlowMgmtTree::Allocate(const FlowMgmtKey *key) {
     632           0 :     return new BridgeRouteFlowMgmtEntry();
     633             : }
     634             : 
     635           0 : bool BridgeRouteFlowMgmtTree::HasVrfFlows(uint32_t vrf,
     636             :                                           Agent::RouteTableType type) {
     637           0 :     BridgeRouteFlowMgmtKey key(vrf, MacAddress::ZeroMac());
     638             :     BridgeRouteFlowMgmtKey *next_key = static_cast<BridgeRouteFlowMgmtKey *>
     639           0 :         (LowerBound(&key));
     640           0 :     if (next_key == NULL)
     641           0 :         return false;
     642             : 
     643           0 :     if (next_key->vrf_id() != vrf)
     644           0 :         return false;
     645             : 
     646           0 :     return true;
     647           0 : }
     648             : 
     649             : /////////////////////////////////////////////////////////////////////////////
     650             : // Vrf Flow Management
     651             : /////////////////////////////////////////////////////////////////////////////
     652           0 : void VrfFlowMgmtTree::ExtractKeys(FlowEntry *flow, FlowMgmtKeyTree *tree) {
     653           0 : }
     654             : 
     655           0 : FlowMgmtEntry *VrfFlowMgmtTree::Allocate(const FlowMgmtKey *key) {
     656           0 :     const VrfEntry *vrf = static_cast<const VrfEntry *>(key->db_entry());
     657           0 :     return new VrfFlowMgmtEntry(this, vrf);
     658             : }
     659             : 
     660           0 : bool VrfFlowMgmtTree::OperEntryAdd(const FlowMgmtRequest *req,
     661             :                                    FlowMgmtKey *key) {
     662           0 :     bool ret = FlowMgmtTree::OperEntryAdd(req, key);
     663             : 
     664           0 :     const VrfEntry *vrf = static_cast<const VrfEntry *>(key->db_entry());
     665           0 :     VrfIdMap::iterator it = id_map_.find(vrf->vrf_id());
     666           0 :     if (it != id_map_.end())
     667           0 :         return ret;
     668             : 
     669           0 :     id_map_.insert(make_pair(vrf->vrf_id(), vrf));
     670           0 :     return ret;
     671             : }
     672             : 
     673           0 : void VrfFlowMgmtTree::FreeNotify(FlowMgmtKey *key, uint32_t gen_id) {
     674           0 :     FlowMgmtTree::FreeNotify(key, gen_id);
     675             : 
     676           0 :     const VrfEntry *vrf = static_cast<const VrfEntry *>(key->db_entry());
     677           0 :     VrfIdMap::iterator it = id_map_.find(vrf->vrf_id());
     678           0 :     if (it != id_map_.end()) {
     679           0 :         id_map_.erase(it);
     680             :     }
     681           0 : }
     682             : 
     683           0 : void VrfFlowMgmtTree::RetryDelete(uint32_t vrf_id) {
     684           0 :     VrfIdMap::iterator it = id_map_.find(vrf_id);
     685           0 :     if (it == id_map_.end())
     686           0 :         return;
     687             : 
     688           0 :     VrfFlowMgmtKey key(it->second);
     689           0 :     const VrfEntry *vrf = dynamic_cast<const VrfEntry *>(key.db_entry());
     690           0 :     if (vrf && vrf->AllRouteTablesEmpty()) {
     691           0 :         FlowMgmtTree::RetryDelete(&key);
     692             :     }
     693           0 : }
     694             : 
     695           0 : void VrfFlowMgmtTree::DeleteDefaultRoute(const VrfEntry *vrf) {
     696             :     //If VMI is associated to FIP, then all non floating-ip
     697             :     //traffic would also be dependent FIP VRF route. This is
     698             :     //to ensure that if more specific route gets added preference
     699             :     //would be given to floating-ip
     700             :     //
     701             :     //Assume a sceanrio where traffic is not NATed, then flow would
     702             :     //add a dependency on default route(assume no default route is
     703             :     //present in FIP VRF). Now if FIP VRF is deleted there is no explicit
     704             :     //trigger to delete this dependencyi and hence delay in releasing VRF
     705             :     //reference, hence if default route DB entry is not present
     706             :     //impliticly delete the default route so that flow could get
     707           0 :     InetRouteFlowMgmtKey key(vrf->vrf_id(), Ip4Address(0), 0);
     708           0 :     FlowMgmtEntry *route_entry = mgr_->ip4_route_flow_mgmt_tree()->Find(&key);
     709           0 :     if (route_entry == NULL ||
     710           0 :         route_entry->oper_state() != FlowMgmtEntry::OPER_NOT_SEEN) {
     711             :         //If entry is not present on it has corresponding DB entry
     712             :         //no need for implicit delete
     713           0 :         return;
     714             :     }
     715             : 
     716           0 :     FlowMgmtRequest route_req(FlowMgmtRequest::IMPLICIT_ROUTE_DELETE);
     717           0 :     FlowMgmtManager::ProcessEvent(
     718           0 :         &route_req, &key, mgr_->ip4_route_flow_mgmt_tree());
     719           0 : }
     720             : 
     721           0 : bool VrfFlowMgmtTree::OperEntryDelete(const FlowMgmtRequest *req,
     722             :                                       FlowMgmtKey *key) {
     723           0 :     const VrfEntry* vrf = static_cast<const VrfEntry *>(req->db_entry());
     724           0 :     DeleteDefaultRoute(vrf);
     725             : 
     726           0 :     return FlowMgmtTree::OperEntryDelete(req, key);
     727             : }

Generated by: LCOV version 1.14