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

Generated by: LCOV version 1.14