LCOV - code coverage report
Current view: top level - vnsw/agent/oper - vm.cc (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 98 155 63.2 %
Date: 2026-06-08 02:02:55 Functions: 15 22 68.2 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
       3             :  */
       4             : 
       5             : #include <boost/uuid/uuid_io.hpp>
       6             : #include <vnc_cfg_types.h>
       7             : #include <cmn/agent_cmn.h>
       8             : 
       9             : #include <ifmap/ifmap_node.h>
      10             : #include <oper/interface_common.h>
      11             : #include <oper/vm.h>
      12             : #include <oper/mirror_table.h>
      13             : #include <oper/agent_sandesh.h>
      14             : #include <oper/config_manager.h>
      15             : 
      16             : using namespace std;
      17             : using namespace autogen;
      18             : using boost::uuids::nil_uuid;
      19             : 
      20             : VmTable *VmTable::vm_table_;
      21             : 
      22         132 : VmEntry::VmEntry(const boost::uuids::uuid &id) : uuid_(id), name_(""),
      23         132 :     drop_new_flows_(false) {
      24         132 :     flow_count_ = 0;
      25         132 :     linklocal_flow_count_ = 0;
      26         132 : }
      27             : 
      28         264 : VmEntry::~VmEntry() {
      29         132 :     assert(flow_count_ == 0);
      30         132 :     assert(linklocal_flow_count_ == 0);
      31         264 : }
      32             : 
      33         349 : bool VmEntry::IsLess(const DBEntry &rhs) const {
      34         349 :     const VmEntry &a = static_cast<const VmEntry &>(rhs);
      35         349 :     return (uuid_ < a.uuid_);
      36             : }
      37             : 
      38           0 : string VmEntry::ToString() const {
      39           0 :     return UuidToString(GetUuid());
      40             : }
      41             : 
      42           0 : DBEntryBase::KeyPtr VmEntry::GetDBRequestKey() const {
      43           0 :     VmKey *key = new VmKey(uuid_);
      44           0 :     return DBEntryBase::KeyPtr(key);
      45             : }
      46             : 
      47           0 : void VmEntry::SetKey(const DBRequestKey *key) {
      48           0 :     const VmKey *k = static_cast<const VmKey *>(key);
      49           0 :     uuid_ = k->uuid_;
      50           0 : }
      51             : 
      52           0 : bool VmEntry::DBEntrySandesh(Sandesh *sresp, std::string &name) const {
      53           0 :     VmListResp *resp = static_cast<VmListResp *>(sresp);
      54             : 
      55           0 :     std::string str_uuid = UuidToString(GetUuid());
      56           0 :     if (name.empty() || str_uuid == name) {
      57           0 :         VmSandeshData data;
      58           0 :         data.set_uuid(str_uuid);
      59             :         std::vector<VmSandeshData> &list =
      60           0 :                 const_cast<std::vector<VmSandeshData>&>(resp->get_vm_list());
      61           0 :         data.set_drop_new_flows(drop_new_flows_);
      62           0 :         list.push_back(data);
      63           0 :         return true;
      64           0 :     }
      65             : 
      66           0 :     return false;
      67           0 : }
      68             : 
      69         272 : void VmEntry::update_flow_count(int val) const {
      70         272 :     VmTable *vm_table = static_cast<VmTable *>(get_table());
      71         272 :     int max_flows = vm_table->agent()->max_vm_flows();
      72         272 :     int tmp = flow_count_.fetch_add(val);
      73             : 
      74         272 :     if (max_flows == FLOWS_LIMIT_UNLIMITED) {
      75             :         // max_flows are not configured,
      76             :         // disable drop new flows and return
      77           0 :         SetInterfacesDropNewFlows(false);
      78           0 :         return;
      79             :     }
      80             : 
      81         272 :     if (val < 0) {
      82         136 :         assert(tmp >= val);
      83         136 :         if ((tmp + val) <
      84         136 :             ((max_flows * (Agent::kDropNewFlowsRecoveryThreshold))/100)) {
      85         136 :             SetInterfacesDropNewFlows(false);
      86             :         }
      87             :     } else {
      88         136 :         if ((tmp + val) >= max_flows) {
      89           0 :             SetInterfacesDropNewFlows(true);
      90             :         }
      91             :     }
      92             : }
      93             : 
      94         136 : void VmEntry::SetInterfacesDropNewFlows(bool drop_new_flows) const {
      95         136 :     if (drop_new_flows_ == drop_new_flows) {
      96         136 :         return;
      97             :     }
      98           0 :     drop_new_flows_ = drop_new_flows;
      99           0 :     VmTable *vm_table = static_cast<VmTable *>(get_table());
     100           0 :     DBRequest req;
     101           0 :     req.oper = DBRequest::DB_ENTRY_ADD_CHANGE;
     102           0 :     std::scoped_lock lock(back_ref_mutex_);
     103           0 :     std::set<IntrusiveReferrer>::const_iterator it = back_ref_set_.begin();
     104           0 :     for (; it != back_ref_set_.end(); it++) {
     105           0 :         VmInterface *vm_intf = static_cast<VmInterface *>((*it).first);
     106           0 :         if (vm_intf->max_flows())
     107           0 :             continue;
     108           0 :         req.key.reset(new VmInterfaceKey(AgentKey::RESYNC,
     109           0 :                                          vm_intf->GetUuid(), ""));
     110           0 :         req.data.reset(new VmInterfaceNewFlowDropData(drop_new_flows));
     111           0 :         vm_table->agent()->interface_table()->Enqueue(&req);
     112             :     }
     113           0 : }
     114             : 
     115          64 : void VmEntry::SendObjectLog(AgentLogEvent::type event) const {
     116          64 :     VmObjectLogInfo info;
     117          64 :     string str;
     118          64 :     string str_uuid = UuidToString(GetUuid());
     119          64 :     vector<string> sg_list;
     120             : 
     121          64 :     switch (event) {
     122          12 :         case AgentLogEvent::ADD:
     123          12 :             str.assign("Addition ");
     124          12 :             break;
     125          14 :         case AgentLogEvent::DEL:
     126          14 :             str.assign("Deletion ");
     127          14 :             break;
     128          38 :         case AgentLogEvent::CHANGE:
     129          38 :             str.assign("Modification ");
     130          38 :             break;
     131           0 :         default:
     132           0 :             str.assign("");
     133           0 :             break;
     134             :     }
     135          64 :     info.set_event(str);
     136          64 :     info.set_uuid(str_uuid);
     137          64 :     if (event != AgentLogEvent::DEL && sg_list.size()) {
     138           0 :         info.set_sg_uuid_list(sg_list);
     139             :     }
     140          64 :     info.set_ref_count(GetRefCount());
     141          64 :     VM_OBJECT_LOG_LOG("AgentVm", SandeshLevel::SYS_INFO, info);
     142          64 : }
     143             : 
     144           0 : boost::uuids::uuid VmTable::GetVmUuid(const std::string &name)
     145             : {
     146           0 :     VmNameUuidTree::iterator it = vm_name_uuid_tree_.find(name);
     147           0 :     if (it != vm_name_uuid_tree_.end()) {
     148           0 :         return it->second;
     149             :     }
     150           0 :     return nil_uuid();
     151             : }
     152             : 
     153         120 : std::unique_ptr<DBEntry> VmTable::AllocEntry(const DBRequestKey *k) const {
     154         120 :     const VmKey *key = static_cast<const VmKey *>(k);
     155         120 :     VmEntry *vm = new VmEntry(key->uuid_);
     156         120 :     return std::unique_ptr<DBEntry>(static_cast<DBEntry *>(vm));
     157             : }
     158             : 
     159          12 : DBEntry *VmTable::OperDBAdd(const DBRequest *req) {
     160          12 :     VmKey *key = static_cast<VmKey *>(req->key.get());
     161          12 :     VmData *data = static_cast<VmData *>(req->data.get());
     162          12 :     VmEntry *vm = new VmEntry(key->uuid_);
     163          12 :     vm->SetCfgName(data->name_);
     164          12 :     vm->SendObjectLog(AgentLogEvent::ADD);
     165          12 :     VmNameUuidTree::iterator it = vm_name_uuid_tree_.find(data->name_);
     166          12 :     if (it != vm_name_uuid_tree_.end()) {
     167           0 :         std::swap(vm_name_uuid_tree_[data->name_], key->uuid_);
     168             :     } else {
     169          12 :         vm_name_uuid_tree_.insert(std::make_pair(data->name_, key->uuid_));
     170             :     }
     171          12 :     return vm;
     172             : }
     173             : 
     174             : // Do DIFF walk for Interface and SG List.
     175          38 : bool VmTable::OperDBOnChange(DBEntry *entry, const DBRequest *req) {
     176          38 :     VmEntry *vm = static_cast<VmEntry *>(entry);
     177          38 :     vm->SendObjectLog(AgentLogEvent::CHANGE);
     178          38 :     return false;
     179             : }
     180             : 
     181          14 : bool VmTable::OperDBDelete(DBEntry *entry, const DBRequest *req) {
     182          14 :     VmEntry *vm = static_cast<VmEntry *>(entry);
     183          14 :     vm->SendObjectLog(AgentLogEvent::DEL);
     184             :     VmNameUuidTree::const_iterator it =
     185          14 :         vm_name_uuid_tree_.find(vm->GetCfgName());
     186          14 :     if (it != vm_name_uuid_tree_.end()) {
     187          12 :         vm_name_uuid_tree_.erase(it->first);
     188             :     }
     189             : 
     190          14 :     return true;
     191             : }
     192             : 
     193           1 : DBTableBase *VmTable::CreateTable(DB *db, const std::string &name) {
     194           1 :     vm_table_ = new VmTable(db, name);
     195           1 :     vm_table_->Init();
     196           1 :     return vm_table_;
     197             : };
     198          64 : bool VmTable::IFNodeToUuid(IFMapNode *node, boost::uuids::uuid &u) {
     199          64 :     VirtualMachine *cfg = static_cast <VirtualMachine *> (node->GetObject());
     200          64 :     assert(cfg);
     201          64 :     autogen::IdPermsType id_perms = cfg->id_perms();
     202          64 :     CfgUuidSet(id_perms.uuid.uuid_mslong, id_perms.uuid.uuid_lslong, u);
     203          64 :     return true;
     204          64 : }
     205             : 
     206          64 : bool VmTable::IFNodeToReq(IFMapNode *node, DBRequest &req,
     207             :         const boost::uuids::uuid &id) {
     208             : 
     209          64 :     if ((req.oper == DBRequest::DB_ENTRY_DELETE) || node->IsDeleted()) {
     210          14 :         req.key.reset(new VmKey(id));
     211          14 :         req.oper = DBRequest::DB_ENTRY_DELETE;
     212          14 :         return true;
     213             :     }
     214             : 
     215          50 :     agent()->config_manager()->AddVmNode(node);
     216          50 :     return false;
     217             : }
     218             : 
     219          50 : bool VmTable::ProcessConfig(IFMapNode *node, DBRequest &req,
     220             :         const boost::uuids::uuid &id) {
     221             : 
     222          50 :     if (node->IsDeleted()) {
     223           0 :         return false;
     224             :     }
     225             : 
     226          50 :     req.key.reset(new VmKey(id));
     227          50 :     VmData::SGUuidList sg_list(0);
     228          50 :     req.data.reset(new VmData(agent(), node, node->name(), sg_list));
     229          50 :     req.oper = DBRequest::DB_ENTRY_ADD_CHANGE;
     230          50 :     return true;
     231          50 : }
     232             : 
     233           0 : void VmListReq::HandleRequest() const {
     234           0 :     AgentSandeshPtr sand(new AgentVmSandesh(context(), get_uuid()));
     235           0 :     sand->DoSandesh(sand);
     236           0 : }
     237             : 
     238           0 : AgentSandeshPtr VmTable::GetAgentSandesh(const AgentSandeshArguments *args,
     239             :                                          const std::string &context) {
     240             :     return AgentSandeshPtr(new AgentVmSandesh(context,
     241           0 :                                               args->GetString("name")));
     242             : }

Generated by: LCOV version 1.14