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

Generated by: LCOV version 1.14