LCOV - code coverage report
Current view: top level - vnsw/agent/uve - vn_uve_table_base.cc (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 118 211 55.9 %
Date: 2026-09-07 02:14:47 Functions: 12 22 54.5 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
       3             :  */
       4             : 
       5             : #include <uve/vn_uve_table_base.h>
       6             : #include <uve/agent_uve_base.h>
       7             : 
       8           2 : VnUveTableBase::VnUveTableBase(Agent *agent, uint32_t default_intvl)
       9           2 :     : uve_vn_map_(), agent_(agent), uve_vn_map_mutex_(),
      10           2 :       vn_listener_id_(DBTableBase::kInvalidId),
      11           2 :       intf_listener_id_(DBTableBase::kInvalidId),
      12           2 :       timer_last_visited_(""),
      13           2 :       timer_(TimerManager::CreateTimer
      14           2 :              (*(agent->event_manager())->io_service(),
      15             :               "VnUveTimer",
      16           2 :               TaskScheduler::GetInstance()->GetTaskId(kTaskDBExclude), 0)) {
      17           2 :       expiry_time_ = default_intvl;
      18           2 :       timer_->Start(expiry_time_,
      19             :                     boost::bind(&VnUveTableBase::TimerExpiry, this));
      20           2 : }
      21             : 
      22           2 : VnUveTableBase::~VnUveTableBase() {
      23           2 : }
      24             : 
      25           1 : void VnUveTableBase::RegisterDBClients() {
      26           1 :     VnTable *vn_table = agent_->vn_table();
      27           1 :     vn_listener_id_ = vn_table->Register
      28           1 :                   (boost::bind(&VnUveTableBase::VnNotify, this, _1, _2));
      29             : 
      30           1 :     InterfaceTable *intf_table = agent_->interface_table();
      31           1 :     intf_listener_id_ = intf_table->Register
      32           1 :                   (boost::bind(&VnUveTableBase::InterfaceNotify, this, _1, _2));
      33           1 :     Add(FlowHandler::UnknownVn());
      34           1 :     Add(FlowHandler::LinkLocalVn());
      35           1 : }
      36             : 
      37           2 : void VnUveTableBase::Shutdown(void) {
      38           2 :     if (vn_listener_id_ != DBTableBase::kInvalidId)
      39           1 :         agent_->vn_table()->Unregister(vn_listener_id_);
      40           2 :     if (intf_listener_id_ != DBTableBase::kInvalidId)
      41           1 :         agent_->interface_table()->Unregister(intf_listener_id_);
      42           2 :     if (timer_) {
      43           2 :         timer_->Cancel();
      44           2 :         TimerManager::DeleteTimer(timer_);
      45           2 :         timer_ = NULL;
      46             :     }
      47           2 : }
      48             : 
      49           0 : bool VnUveTableBase::TimerExpiry() {
      50           0 :     UveVnMap::iterator it = uve_vn_map_.lower_bound(timer_last_visited_);
      51           0 :     if (it == uve_vn_map_.end()) {
      52           0 :         timer_last_visited_ = "";
      53           0 :         return true;
      54             :     }
      55             : 
      56           0 :     uint32_t count = 0;
      57           0 :     while (it != uve_vn_map_.end() && count < AgentUveBase::kUveCountPerTimer) {
      58           0 :         VnUveEntryBase *entry = it->second.get();
      59           0 :         UveVnMap::iterator prev = it;
      60           0 :         it++;
      61           0 :         count++;
      62             : 
      63           0 :         if (entry->deleted()) {
      64           0 :             SendDeleteVnMsg(prev->first);
      65           0 :             if (!entry->renewed()) {
      66           0 :                 Delete(prev->first);
      67             :             } else {
      68           0 :                 entry->set_deleted(false);
      69           0 :                 entry->set_renewed(false);
      70           0 :                 entry->set_changed(false);
      71           0 :                 SendVnMsg(entry, entry->vn());
      72             :                 // Send VN ACE stats
      73           0 :                 SendVnAceStats(entry, entry->vn());
      74             :             }
      75             :         } else {
      76           0 :             if (entry->changed()) {
      77           0 :                 SendVnMsg(entry, entry->vn());
      78           0 :                 entry->set_changed(false);
      79             :                 /* Clear renew flag to be on safer side. Not really required */
      80           0 :                 entry->set_renewed(false);
      81             :             }
      82             : 
      83             :             // Send VN ACE stats
      84           0 :             SendVnAceStats(entry, entry->vn());
      85             :         }
      86             :     }
      87             : 
      88           0 :     if (it == uve_vn_map_.end()) {
      89           0 :         timer_last_visited_ = "";
      90           0 :         set_expiry_time(agent_->uve()->default_interval());
      91             :     } else {
      92           0 :         timer_last_visited_ = it->first;
      93           0 :         set_expiry_time(agent_->uve()->incremental_interval());
      94             :     }
      95           0 :     return true;
      96             : }
      97             : 
      98           0 : void VnUveTableBase::set_expiry_time(int time) {
      99           0 :     if (time != expiry_time_) {
     100           0 :         expiry_time_ = time;
     101           0 :         timer_->Reschedule(expiry_time_);
     102             :     }
     103           0 : }
     104             : 
     105           0 : void VnUveTableBase::SendVnMsg(VnUveEntryBase *entry, const VnEntry *vn) {
     106           0 :     UveVirtualNetworkAgent uve;
     107           0 :     if (vn == NULL) {
     108           0 :         return;
     109             :     }
     110           0 :     if (entry->FrameVnMsg(vn, uve)) {
     111           0 :         DispatchVnMsg(uve);
     112             :     }
     113           0 : }
     114             : 
     115           0 : void VnUveTableBase::DispatchVnMsg(const UveVirtualNetworkAgent &uve) {
     116           0 :     UveVirtualNetworkAgentTrace::Send(uve);
     117           0 : }
     118             : 
     119          23 : VnUveEntryBase* VnUveTableBase::UveEntryFromVn(const VnEntry *vn) {
     120          23 :     if (vn->GetName() == agent_->NullString()) {
     121           0 :        return NULL;
     122             :     }
     123             : 
     124          23 :     UveVnMap::iterator it = uve_vn_map_.find(vn->GetName());
     125          23 :     if (it == uve_vn_map_.end()) {
     126           0 :         return NULL;
     127             :     }
     128          23 :     return it->second.get();
     129             : }
     130             : 
     131          16 : void VnUveTableBase::MarkChanged(const VnEntry *vn) {
     132          16 :     VnUveEntryBase* entry = UveEntryFromVn(vn);
     133          16 :     if (entry == NULL) {
     134           0 :         return;
     135             :     }
     136             : 
     137          16 :     entry->set_changed(true);
     138          16 :     return;
     139             : }
     140             : 
     141           0 : void VnUveTableBase::SendDeleteVnMsg(const string &vn) {
     142           0 :     UveVirtualNetworkAgent s_vn;
     143           0 :     s_vn.set_name(vn);
     144           0 :     s_vn.set_deleted(true);
     145           0 :     DispatchVnMsg(s_vn);
     146           0 : }
     147             : 
     148           0 : void VnUveTableBase::Delete(const std::string &name) {
     149           0 :     UveVnMap::iterator it = uve_vn_map_.find(name);
     150           0 :     if (it != uve_vn_map_.end()) {
     151           0 :         std::scoped_lock lock(uve_vn_map_mutex_);
     152           0 :         uve_vn_map_.erase(it);
     153           0 :     }
     154           0 : }
     155             : 
     156          22 : VnUveEntryBase* VnUveTableBase::Add(const VnEntry *vn) {
     157          22 :     VnUveEntryPtr uve = Allocate(vn);
     158          22 :     pair<UveVnMap::iterator, bool> ret;
     159          22 :     ret = uve_vn_map_.insert(UveVnPair(vn->GetName(), uve));
     160          22 :     UveVnMap::iterator it = ret.first;
     161          22 :     VnUveEntryBase* entry = it->second.get();
     162          22 :     entry->set_vn(vn);
     163          22 :     if (entry->deleted()) {
     164          20 :         entry->set_renewed(true);
     165             :     }
     166             : 
     167          22 :     return entry;
     168          22 : }
     169             : 
     170           2 : void VnUveTableBase::Add(const string &vn) {
     171           2 :     VnUveEntryPtr uve = Allocate();
     172           2 :     uve_vn_map_.insert(UveVnPair(vn, uve));
     173           2 : }
     174             : 
     175           0 : VnUveTableBase::VnUveEntryPtr VnUveTableBase::Allocate(const VnEntry *vn) {
     176           0 :     VnUveEntryPtr uve(new VnUveEntryBase(agent_, vn));
     177           0 :     return uve;
     178             : }
     179             : 
     180           0 : VnUveTableBase::VnUveEntryPtr VnUveTableBase::Allocate() {
     181           0 :     VnUveEntryPtr uve(new VnUveEntryBase(agent_));
     182           0 :     return uve;
     183             : }
     184             : 
     185          23 : void VnUveTableBase::VnNotify(DBTablePartBase *partition, DBEntryBase *e) {
     186          23 :     const VnEntry *vn = static_cast<const VnEntry *>(e);
     187             : 
     188             :     DBState *state = static_cast<DBState *>
     189          23 :         (e->GetState(partition->parent(), vn_listener_id_));
     190             : 
     191          23 :     if (e->IsDeleted()) {
     192           7 :         if (state) {
     193           7 :             VnUveEntryBase *uve = UveEntryFromVn(vn);
     194           7 :             if (uve) {
     195             :                 /* The Reset API sets 'deleted' flag and resets 'renewed' and
     196             :                  * 'add_by_vn_notify' flags */
     197           7 :                 uve->Reset();
     198             :             }
     199             : 
     200           7 :             e->ClearState(partition->parent(), vn_listener_id_);
     201           7 :             delete state;
     202             :         }
     203           7 :         return;
     204             :     }
     205             : 
     206          16 :     if (!state) {
     207           7 :         state = new DBState();
     208           7 :         e->SetState(partition->parent(), vn_listener_id_, state);
     209             : 
     210           7 :         VnUveEntryBase* entry = Add(vn);
     211           7 :         entry->set_add_by_vn_notify(true);
     212             :     }
     213          16 :     MarkChanged(vn);
     214             : }
     215             : 
     216          15 : void VnUveTableBase::InterfaceDeleteHandler(const string &vm, const string &vn,
     217             :                                         const Interface* intf) {
     218          15 :     if (vn == agent_->NullString()) {
     219           0 :         return;
     220             :     }
     221             : 
     222          15 :     UveVnMap::iterator it = uve_vn_map_.find(vn);
     223          15 :     if (it == uve_vn_map_.end()) {
     224           0 :         return;
     225             :     }
     226             : 
     227          15 :     VnUveEntryPtr vn_uve_entry_ptr(it->second);
     228          15 :     VnUveEntryBase *vn_uve_entry = vn_uve_entry_ptr.get();
     229          30 :     UveVirtualNetworkAgent uve;
     230             : 
     231          15 :     vn_uve_entry->VmDelete(vm);
     232          15 :     vn_uve_entry->InterfaceDelete(intf);
     233          15 :     vn_uve_entry->set_changed(true);
     234          15 :     return;
     235          15 : }
     236             : 
     237          15 : void VnUveTableBase::InterfaceAddHandler(const VnEntry* vn,
     238             :                                          const Interface* intf,
     239             :                                          const string &vm_name,
     240             :                                          VnUveInterfaceState *state) {
     241             :     VnUveEntryBase *vn_uve_entry;
     242          15 :     vn_uve_entry = Add(vn);
     243             : 
     244          30 :     UveVirtualNetworkAgent uve;
     245             : 
     246          15 :     if (vm_name != state->vm_name_) {
     247           0 :         if (state->vm_name_.length()) {
     248           0 :             vn_uve_entry->VmDelete(state->vm_name_);
     249             :         }
     250             :     }
     251          15 :     if (vm_name.length()) {
     252          15 :         vn_uve_entry->VmAdd(vm_name);
     253             :     }
     254          15 :     vn_uve_entry->InterfaceAdd(intf);
     255          15 :     vn_uve_entry->set_changed(true);
     256          30 :     return;
     257          15 : }
     258             : 
     259          86 : void VnUveTableBase::InterfaceNotify(DBTablePartBase *partition, DBEntryBase *e) {
     260          86 :     const VmInterface *vm_port = dynamic_cast<const VmInterface*>(e);
     261          86 :     if (vm_port == NULL) {
     262          15 :         return;
     263             :     }
     264             : 
     265             :     VnUveInterfaceState *state = static_cast<VnUveInterfaceState *>
     266          71 :                       (e->GetState(partition->parent(), intf_listener_id_));
     267          71 :     if (e->IsDeleted() || (vm_port->vn() == NULL)) {
     268          32 :         if (state) {
     269          15 :             InterfaceDeleteHandler(state->vm_name_, state->vn_name_,
     270             :                                    vm_port);
     271          15 :             e->ClearState(partition->parent(), intf_listener_id_);
     272          15 :             delete state;
     273             :         }
     274             :     } else {
     275          39 :         const VnEntry *vn = vm_port->vn();
     276          39 :         const VmEntry *vm = vm_port->vm();
     277          39 :         std::string vm_name = vm? vm->GetCfgName() : agent_->NullString();
     278             : 
     279          39 :         if (!state) {
     280          15 :             state = new VnUveInterfaceState(vm_name, vn->GetName());
     281          15 :             e->SetState(partition->parent(), intf_listener_id_, state);
     282          15 :             InterfaceAddHandler(vn, vm_port, vm_name, state);
     283             :         } else {
     284          24 :             if (state->vn_name_.compare(vn->GetName()) != 0) {
     285           0 :                 InterfaceDeleteHandler(state->vm_name_, state->vn_name_,
     286             :                                        vm_port);
     287           0 :                 state->vm_name_ = vm_name;
     288           0 :                 state->vn_name_ = vn->GetName();
     289           0 :                 InterfaceAddHandler(vn, vm_port, vm_name, state);
     290           0 :                 return;
     291             :             }
     292          24 :             if (state->vm_name_.compare(vm_name) != 0) {
     293           0 :                 InterfaceAddHandler(vn, vm_port, vm_name, state);
     294           0 :                 state->vm_name_ = vm_name;
     295             :             }
     296             :         }
     297          39 :     }
     298          71 :     return;
     299             : }
     300             : 
     301           0 : void VnUveTableBase::SendVnAclRuleCount() {
     302           0 :     UveVnMap::const_iterator it = uve_vn_map_.begin();
     303           0 :     while (it != uve_vn_map_.end()) {
     304           0 :         VnUveEntryBase *entry = it->second.get();
     305           0 :         ++it;
     306           0 :         if (entry->deleted()) {
     307           0 :             continue;
     308             :         }
     309           0 :         if (entry->vn()) {
     310           0 :             UveVirtualNetworkAgent uve;
     311           0 :             bool send = entry->FrameVnAclRuleCountMsg(entry->vn(), &uve);
     312           0 :             if (send) {
     313           0 :                 DispatchVnMsg(uve);
     314             :             }
     315           0 :         }
     316             :     }
     317           0 : }

Generated by: LCOV version 1.14