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-08-03 02:19:58 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           6 : VnUveTableBase::VnUveTableBase(Agent *agent, uint32_t default_intvl)
       9           6 :     : uve_vn_map_(), agent_(agent), uve_vn_map_mutex_(),
      10           6 :       vn_listener_id_(DBTableBase::kInvalidId),
      11           6 :       intf_listener_id_(DBTableBase::kInvalidId),
      12           6 :       timer_last_visited_(""),
      13           6 :       timer_(TimerManager::CreateTimer
      14           6 :              (*(agent->event_manager())->io_service(),
      15             :               "VnUveTimer",
      16           6 :               TaskScheduler::GetInstance()->GetTaskId(kTaskDBExclude), 0)) {
      17           6 :       expiry_time_ = default_intvl;
      18           6 :       timer_->Start(expiry_time_,
      19             :                     boost::bind(&VnUveTableBase::TimerExpiry, this));
      20           6 : }
      21             : 
      22           6 : VnUveTableBase::~VnUveTableBase() {
      23           6 : }
      24             : 
      25           3 : void VnUveTableBase::RegisterDBClients() {
      26           3 :     VnTable *vn_table = agent_->vn_table();
      27           3 :     vn_listener_id_ = vn_table->Register
      28           3 :                   (boost::bind(&VnUveTableBase::VnNotify, this, _1, _2));
      29             : 
      30           3 :     InterfaceTable *intf_table = agent_->interface_table();
      31           3 :     intf_listener_id_ = intf_table->Register
      32           3 :                   (boost::bind(&VnUveTableBase::InterfaceNotify, this, _1, _2));
      33           3 :     Add(FlowHandler::UnknownVn());
      34           3 :     Add(FlowHandler::LinkLocalVn());
      35           3 : }
      36             : 
      37           6 : void VnUveTableBase::Shutdown(void) {
      38           6 :     if (vn_listener_id_ != DBTableBase::kInvalidId)
      39           3 :         agent_->vn_table()->Unregister(vn_listener_id_);
      40           6 :     if (intf_listener_id_ != DBTableBase::kInvalidId)
      41           3 :         agent_->interface_table()->Unregister(intf_listener_id_);
      42           6 :     if (timer_) {
      43           6 :         timer_->Cancel();
      44           6 :         TimerManager::DeleteTimer(timer_);
      45           6 :         timer_ = NULL;
      46             :     }
      47           6 : }
      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          19 : VnUveEntryBase* VnUveTableBase::UveEntryFromVn(const VnEntry *vn) {
     120          19 :     if (vn->GetName() == agent_->NullString()) {
     121           0 :        return NULL;
     122             :     }
     123             : 
     124          19 :     UveVnMap::iterator it = uve_vn_map_.find(vn->GetName());
     125          19 :     if (it == uve_vn_map_.end()) {
     126           0 :         return NULL;
     127             :     }
     128          19 :     return it->second.get();
     129             : }
     130             : 
     131          13 : void VnUveTableBase::MarkChanged(const VnEntry *vn) {
     132          13 :     VnUveEntryBase* entry = UveEntryFromVn(vn);
     133          13 :     if (entry == NULL) {
     134           0 :         return;
     135             :     }
     136             : 
     137          13 :     entry->set_changed(true);
     138          13 :     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          20 : VnUveEntryBase* VnUveTableBase::Add(const VnEntry *vn) {
     157          20 :     VnUveEntryPtr uve = Allocate(vn);
     158          20 :     pair<UveVnMap::iterator, bool> ret;
     159          20 :     ret = uve_vn_map_.insert(UveVnPair(vn->GetName(), uve));
     160          20 :     UveVnMap::iterator it = ret.first;
     161          20 :     VnUveEntryBase* entry = it->second.get();
     162          20 :     entry->set_vn(vn);
     163          20 :     if (entry->deleted()) {
     164          18 :         entry->set_renewed(true);
     165             :     }
     166             : 
     167          20 :     return entry;
     168          20 : }
     169             : 
     170           6 : void VnUveTableBase::Add(const string &vn) {
     171           6 :     VnUveEntryPtr uve = Allocate();
     172           6 :     uve_vn_map_.insert(UveVnPair(vn, uve));
     173           6 : }
     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          19 : void VnUveTableBase::VnNotify(DBTablePartBase *partition, DBEntryBase *e) {
     186          19 :     const VnEntry *vn = static_cast<const VnEntry *>(e);
     187             : 
     188             :     DBState *state = static_cast<DBState *>
     189          19 :         (e->GetState(partition->parent(), vn_listener_id_));
     190             : 
     191          19 :     if (e->IsDeleted()) {
     192           6 :         if (state) {
     193           6 :             VnUveEntryBase *uve = UveEntryFromVn(vn);
     194           6 :             if (uve) {
     195             :                 /* The Reset API sets 'deleted' flag and resets 'renewed' and
     196             :                  * 'add_by_vn_notify' flags */
     197           6 :                 uve->Reset();
     198             :             }
     199             : 
     200           6 :             e->ClearState(partition->parent(), vn_listener_id_);
     201           6 :             delete state;
     202             :         }
     203           6 :         return;
     204             :     }
     205             : 
     206          13 :     if (!state) {
     207           6 :         state = new DBState();
     208           6 :         e->SetState(partition->parent(), vn_listener_id_, state);
     209             : 
     210           6 :         VnUveEntryBase* entry = Add(vn);
     211           6 :         entry->set_add_by_vn_notify(true);
     212             :     }
     213          13 :     MarkChanged(vn);
     214             : }
     215             : 
     216          14 : void VnUveTableBase::InterfaceDeleteHandler(const string &vm, const string &vn,
     217             :                                         const Interface* intf) {
     218          14 :     if (vn == agent_->NullString()) {
     219           0 :         return;
     220             :     }
     221             : 
     222          14 :     UveVnMap::iterator it = uve_vn_map_.find(vn);
     223          14 :     if (it == uve_vn_map_.end()) {
     224           0 :         return;
     225             :     }
     226             : 
     227          14 :     VnUveEntryPtr vn_uve_entry_ptr(it->second);
     228          14 :     VnUveEntryBase *vn_uve_entry = vn_uve_entry_ptr.get();
     229          28 :     UveVirtualNetworkAgent uve;
     230             : 
     231          14 :     vn_uve_entry->VmDelete(vm);
     232          14 :     vn_uve_entry->InterfaceDelete(intf);
     233          14 :     vn_uve_entry->set_changed(true);
     234          14 :     return;
     235          14 : }
     236             : 
     237          14 : void VnUveTableBase::InterfaceAddHandler(const VnEntry* vn,
     238             :                                          const Interface* intf,
     239             :                                          const string &vm_name,
     240             :                                          VnUveInterfaceState *state) {
     241             :     VnUveEntryBase *vn_uve_entry;
     242          14 :     vn_uve_entry = Add(vn);
     243             : 
     244          28 :     UveVirtualNetworkAgent uve;
     245             : 
     246          14 :     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          14 :     if (vm_name.length()) {
     252          14 :         vn_uve_entry->VmAdd(vm_name);
     253             :     }
     254          14 :     vn_uve_entry->InterfaceAdd(intf);
     255          14 :     vn_uve_entry->set_changed(true);
     256          28 :     return;
     257          14 : }
     258             : 
     259          98 : void VnUveTableBase::InterfaceNotify(DBTablePartBase *partition, DBEntryBase *e) {
     260          98 :     const VmInterface *vm_port = dynamic_cast<const VmInterface*>(e);
     261          98 :     if (vm_port == NULL) {
     262          27 :         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          34 :         if (state) {
     269          14 :             InterfaceDeleteHandler(state->vm_name_, state->vn_name_,
     270             :                                    vm_port);
     271          14 :             e->ClearState(partition->parent(), intf_listener_id_);
     272          14 :             delete state;
     273             :         }
     274             :     } else {
     275          37 :         const VnEntry *vn = vm_port->vn();
     276          37 :         const VmEntry *vm = vm_port->vm();
     277          37 :         std::string vm_name = vm? vm->GetCfgName() : agent_->NullString();
     278             : 
     279          37 :         if (!state) {
     280          14 :             state = new VnUveInterfaceState(vm_name, vn->GetName());
     281          14 :             e->SetState(partition->parent(), intf_listener_id_, state);
     282          14 :             InterfaceAddHandler(vn, vm_port, vm_name, state);
     283             :         } else {
     284          23 :             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          23 :             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          37 :     }
     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