LCOV - code coverage report
Current view: top level - vnsw/agent/oper - qos_config.cc (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 21 292 7.2 %
Date: 2026-06-04 02:06:09 Functions: 8 33 24.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 <cmn/agent.h>
       6             : #include <vnc_cfg_types.h>
       7             : #include <agent_types.h>
       8             : #include <oper/agent_sandesh.h>
       9             : #include <cfg/cfg_init.h>
      10             : #include <oper_db.h>
      11             : #include <oper/config_manager.h>
      12             : #include <oper/interface_common.h>
      13             : #include <forwarding_class.h>
      14             : #include <qos_config.h>
      15             : #include <resource_manager/resource_manager.h>
      16             : #include <resource_manager/resource_table.h>
      17             : #include <resource_manager/qos_index.h>
      18             : 
      19             : using namespace autogen;
      20         228 : AgentQosConfig::AgentQosConfig(const boost::uuids::uuid uuid):
      21         228 :     uuid_(uuid), id_(AgentQosConfigTable::kInvalidIndex) {
      22         228 : }
      23             : 
      24         456 : AgentQosConfig::~AgentQosConfig() {
      25         228 :     if (id_ != AgentQosConfigTable::kInvalidIndex) {
      26           0 :         static_cast<AgentQosConfigTable *>(get_table())->ReleaseIndex(this);
      27             :     }
      28         456 : }
      29             : 
      30           0 : DBEntryBase::KeyPtr AgentQosConfig::GetDBRequestKey() const {
      31           0 :     AgentQosConfigKey *key = new AgentQosConfigKey(uuid_);
      32           0 :     return DBEntryBase::KeyPtr(key);
      33             : }
      34             : 
      35           0 : std::string AgentQosConfig::ToString() const {
      36           0 :     std::ostringstream buffer;
      37           0 :     buffer << uuid_;
      38           0 :     return buffer.str();
      39           0 : }
      40             : 
      41           0 : bool AgentQosConfig::DBEntrySandesh(Sandesh *sresp, std::string &name) const {
      42           0 :     AgentQosConfigSandeshResp *resp =
      43             :         static_cast<AgentQosConfigSandeshResp *>(sresp);
      44           0 :     AgentQosConfigSandeshData data;
      45             : 
      46           0 :     data.set_uuid(UuidToString(uuid_));
      47           0 :     data.set_name(name_);
      48           0 :     data.set_id(id_);
      49           0 :     if (type_ == VHOST) {
      50           0 :         data.set_type("vhost");
      51           0 :     } else if (type_ == FABRIC) {
      52           0 :         data.set_type("fabric");
      53             :     } else {
      54           0 :         data.set_type("default");
      55             :     }
      56             : 
      57           0 :     std::vector<QosForwardingClassSandeshPair> dscp_list;
      58             :     AgentQosConfig::QosIdForwardingClassMap::const_iterator it =
      59           0 :         dscp_map_.begin();
      60           0 :     for(; it != dscp_map_.end(); it++) {
      61           0 :         QosForwardingClassSandeshPair pair;
      62           0 :         pair.set_qos_value(it->first);
      63           0 :         pair.set_forwarding_class_id(it->second);
      64           0 :         dscp_list.push_back(pair);
      65           0 :     }
      66             : 
      67           0 :     std::vector<QosForwardingClassSandeshPair> vlan_priority_list;
      68           0 :     it = vlan_priority_map_.begin();
      69           0 :     for(; it != vlan_priority_map_.end(); it++) {
      70           0 :         QosForwardingClassSandeshPair pair;
      71           0 :         pair.set_qos_value(it->first);
      72           0 :         pair.set_forwarding_class_id(it->second);
      73           0 :         vlan_priority_list.push_back(pair);
      74           0 :     }
      75             : 
      76           0 :     std::vector<QosForwardingClassSandeshPair> mpls_exp_list;
      77           0 :     it = mpls_exp_map_.begin();
      78           0 :     for(; it != mpls_exp_map_.end(); it++) {
      79           0 :         QosForwardingClassSandeshPair pair;
      80           0 :         pair.set_qos_value(it->first);
      81           0 :         pair.set_forwarding_class_id(it->second);
      82           0 :         mpls_exp_list.push_back(pair);
      83           0 :     }
      84             : 
      85           0 :     data.set_dscp_list(dscp_list);
      86           0 :     data.set_vlan_priority_list(vlan_priority_list);
      87           0 :     data.set_mpls_exp_list(mpls_exp_list);
      88           0 :     data.set_default_forwarding_class(default_forwarding_class_);
      89             : 
      90             :     std::vector<AgentQosConfigSandeshData> &list =
      91           0 :         const_cast<std::vector<AgentQosConfigSandeshData>&>(resp->get_qc_list());
      92           0 :     list.push_back(data);
      93           0 :     return true;
      94           0 : }
      95             : 
      96           0 : bool AgentQosConfig::IsLess(const DBEntry &rhs) const {
      97           0 :     const AgentQosConfig &fc = static_cast<const AgentQosConfig &>(rhs);
      98           0 :     return (uuid_ < fc.uuid_);
      99             : }
     100             : 
     101           0 : bool AgentQosConfig::HandleQosForwardingMapChange(const Agent *agent,
     102             :                                                   QosIdForwardingClassMap &map,
     103             :                                                   const
     104             :                                                   AgentQosIdForwardingClassMap
     105             :                                                   &data_map) {
     106             : 
     107           0 :     QosIdForwardingClassMap new_map;
     108           0 :     AgentQosIdForwardingClassMap::const_iterator it = data_map.begin();
     109           0 :     for (; it != data_map.end(); it++) {
     110           0 :         new_map.insert(QosIdForwardingClassPair(it->first, it->second));
     111             :     }
     112             : 
     113           0 :     if (map != new_map) {
     114           0 :         map = new_map;
     115           0 :         return true;
     116             :     }
     117             : 
     118           0 :     return false;
     119           0 : }
     120             : 
     121           0 : bool AgentQosConfig::VerifyLinkToGlobalQosConfig(const Agent *agent,
     122             :                                                  const AgentQosConfigData *data) {
     123           0 :     IFMapNode *node = data->ifmap_node();
     124           0 :     IFMapAgentTable *table = static_cast<IFMapAgentTable *>(node->table());
     125             : 
     126           0 :     for (DBGraphVertex::adjacency_iterator iter =
     127           0 :          node->begin(table->GetGraph()); iter != node->end(table->GetGraph());
     128           0 :          ++iter) {
     129           0 :         const IFMapNode *adj_node = static_cast<const IFMapNode *>(iter.operator->());
     130           0 :         if (adj_node->table() == agent->cfg()->cfg_global_qos_table()) {
     131           0 :             return true;
     132             :         }
     133             :     }
     134           0 :     return false;
     135             : }
     136             : 
     137           0 : void AgentQosConfig::HandleVhostQosConfig(const Agent *agent,
     138             :         const AgentQosConfigData *data, bool deleted) {
     139           0 :     if (deleted == false) {
     140             :         //Verify that link to Global QoS config exists
     141           0 :         if (VerifyLinkToGlobalQosConfig(agent, data) == false) {
     142           0 :             deleted = true;
     143             :         }
     144             :     }
     145             : 
     146             :     AgentQosConfigTable *table =
     147           0 :         static_cast<AgentQosConfigTable *>(agent->qos_config_table());
     148             : 
     149           0 :     if (deleted) {
     150           0 :         table->EraseVhostQosConfig(uuid());
     151             :     } else {
     152           0 :         table->InsertVhostQosConfig(uuid());
     153             :     }
     154             : 
     155           0 :     DBRequest req(DBRequest::DB_ENTRY_ADD_CHANGE);
     156             :     VmInterfaceKey *key =
     157           0 :         new VmInterfaceKey(AgentKey::ADD_DEL_CHANGE, boost::uuids::nil_uuid(),
     158           0 :                            agent->vhost_interface_name());
     159           0 :     key->sub_op_ = AgentKey::RESYNC;
     160           0 :     boost::uuids::uuid qos_config_uuid = table->GetActiveVhostQosConfig();
     161             :     InterfaceQosConfigData *qos_data =
     162           0 :         new InterfaceQosConfigData(agent, NULL, qos_config_uuid);
     163           0 :     req.key.reset(key);
     164           0 :     req.data.reset(qos_data);
     165           0 :     agent->interface_table()->Enqueue(&req);
     166           0 : }
     167             : 
     168           0 : void AgentQosConfig::HandleFabricQosConfig(const Agent *agent,
     169             :         const AgentQosConfigData *data, bool deleted) {
     170             : 
     171           0 :     if (deleted == false) {
     172             :         //Verify that link to Global QoS config exists
     173           0 :         if (VerifyLinkToGlobalQosConfig(agent, data) == false) {
     174           0 :             deleted = true;
     175             :         }
     176             :     }
     177             : 
     178             :     AgentQosConfigTable *table =
     179           0 :         static_cast<AgentQosConfigTable *>(agent->qos_config_table());
     180             : 
     181           0 :     if (deleted) {
     182           0 :         table->EraseFabricQosConfig(uuid());
     183             :     } else {
     184           0 :         table->InsertFabricQosConfig(uuid());
     185             :     }
     186             : 
     187           0 :     DBRequest req(DBRequest::DB_ENTRY_ADD_CHANGE);
     188             :     PhysicalInterfaceKey *key =
     189           0 :         new PhysicalInterfaceKey(agent->fabric_interface_name());
     190           0 :     key->sub_op_ = AgentKey::RESYNC;
     191             : 
     192           0 :     boost::uuids::uuid qos_config_uuid = table->GetActiveFabricQosConfig();
     193             :     InterfaceQosConfigData *qos_data =
     194           0 :         new InterfaceQosConfigData(agent, NULL, qos_config_uuid);
     195           0 :     req.key.reset(key);
     196           0 :     req.data.reset(qos_data);
     197           0 :     agent->interface_table()->Enqueue(&req);
     198           0 : }
     199             : 
     200           0 : void AgentQosConfig::HandleGlobalQosConfig(const AgentQosConfigData *data) {
     201           0 :     if (data->ifmap_node() == NULL) {
     202           0 :         return;
     203             :     }
     204           0 :     if (type_ == VHOST) {
     205           0 :         HandleVhostQosConfig(data->agent(), data, false);
     206             :     } else {
     207           0 :         HandleFabricQosConfig(data->agent(), data, false);
     208             :     }
     209             : }
     210             : 
     211           0 : bool AgentQosConfig::Change(const DBRequest *req) {
     212           0 :     bool ret = false;
     213             :     const AgentQosConfigData *data =
     214           0 :         static_cast<const AgentQosConfigData *>(req->data.get());
     215             : 
     216             :     //Ignore change notification if entry node is marked for deletion
     217           0 :     if ((data->ifmap_node() == NULL) || (data->ifmap_node()->IsDeleted())) {
     218           0 :         return ret;
     219             :     }
     220             : 
     221           0 :     if (name_ != data->name_) {
     222           0 :         name_ = data->name_;
     223           0 :         ret = true;
     224             :     }
     225             : 
     226           0 :     if (HandleQosForwardingMapChange(data->agent(), dscp_map_, data->dscp_map_)) {
     227           0 :         ret = true;
     228             :     }
     229             : 
     230           0 :     if (HandleQosForwardingMapChange(data->agent(), vlan_priority_map_,
     231           0 :                                      data->vlan_priority_map_)) {
     232           0 :         ret = true;
     233             :     }
     234             : 
     235           0 :     if (HandleQosForwardingMapChange(data->agent(), mpls_exp_map_,
     236           0 :                                      data->mpls_exp_map_)) {
     237           0 :         ret = true;
     238             :     }
     239             : 
     240           0 :     if (type_ != data->type_) {
     241           0 :         type_ = data->type_;
     242           0 :         ret = true;
     243             :     }
     244             : 
     245           0 :     if (type_ != DEFAULT) {
     246           0 :         HandleGlobalQosConfig(data);
     247             :     }
     248             : 
     249           0 :     if (default_forwarding_class_ != data->default_forwarding_class_) {
     250           0 :         default_forwarding_class_ = data->default_forwarding_class_;
     251           0 :         ret = true;
     252             :     }
     253             : 
     254           0 :     return ret;
     255             : }
     256             : 
     257           0 : void AgentQosConfig::Delete(const DBRequest *req) {
     258           0 :     Agent *agent = (static_cast<AgentOperDBTable *>(get_table())->agent());
     259           0 :     if (type_ == VHOST) {
     260           0 :         HandleVhostQosConfig(agent, NULL, true);
     261           0 :     } else if (type_ == FABRIC) {
     262           0 :         HandleFabricQosConfig(agent, NULL, true);
     263             :     }
     264           0 : }
     265             : 
     266           0 : void AgentQosConfig::SetKey(const DBRequestKey *key) {
     267           0 :     const AgentQosConfigKey *fc_key =
     268             :         static_cast<const AgentQosConfigKey *>(key);
     269           0 :     uuid_ = fc_key->uuid_;
     270           0 : }
     271             : 
     272           2 : AgentQosConfigTable::AgentQosConfigTable(Agent *agent,
     273           2 :                                          DB *db, const std::string &name):
     274           2 :     AgentOperDBTable(db, name) {
     275           2 :     set_agent(agent);
     276           2 : }
     277             : 
     278           4 : AgentQosConfigTable::~AgentQosConfigTable() {
     279           4 : }
     280             : 
     281             : DBTableBase*
     282           2 : AgentQosConfigTable::CreateTable(Agent *agent, DB *db, const std::string &name) {
     283           2 :     AgentQosConfigTable *qos_table = new AgentQosConfigTable(agent, db, name);
     284           2 :     (static_cast<DBTable *>(qos_table))->Init();
     285           2 :     return qos_table;
     286             : }
     287             : 
     288             : std::unique_ptr<DBEntry>
     289         228 : AgentQosConfigTable::AllocEntry(const DBRequestKey *k) const {
     290         228 :     const AgentQosConfigKey *key =
     291             :         static_cast<const AgentQosConfigKey *>(k);
     292         228 :     AgentQosConfig *fc = new AgentQosConfig(key->uuid_);
     293         228 :     return std::unique_ptr<DBEntry>(static_cast<DBEntry *>(fc));
     294             : }
     295             : 
     296           0 : DBEntry* AgentQosConfigTable::OperDBAdd(const DBRequest *req) {
     297             :     const AgentQosConfigKey *key =
     298           0 :         static_cast<const AgentQosConfigKey *>(req->key.get());
     299           0 :     AgentQosConfig *qc = new AgentQosConfig(key->uuid_);
     300             :     ResourceManager::KeyPtr rkey(new QosIndexResourceKey(
     301           0 :                                  agent()->resource_manager(), key->uuid_));
     302             :     int id = static_cast<IndexResourceData *>(agent()->resource_manager()->
     303           0 :                                                Allocate(rkey).get())->index();
     304           0 :     index_table_.InsertAtIndex(id, qc);
     305           0 :     qc->set_id(id);
     306           0 :     qc->Change(req);
     307           0 :     name_map_.insert(AgentQosConfigNamePair(qc->name(), qc));
     308           0 :     return static_cast<DBEntry *>(qc);
     309           0 : }
     310             : 
     311           0 : bool AgentQosConfigTable::OperDBOnChange(DBEntry *entry, const DBRequest *req) {
     312           0 :     AgentQosConfig *qc = static_cast<AgentQosConfig *>(entry);
     313           0 :     return qc->Change(req);
     314             : }
     315             : 
     316           0 : bool AgentQosConfigTable::OperDBResync(DBEntry *entry, const DBRequest *req) {
     317           0 :     return OperDBOnChange(entry, req);
     318             : }
     319             : 
     320           0 : bool AgentQosConfigTable::OperDBDelete(DBEntry *entry, const DBRequest *req) {
     321           0 :     AgentQosConfig *qc = static_cast<AgentQosConfig *>(entry);
     322           0 :     qc->Delete(req);
     323           0 :     name_map_.erase(qc->name());
     324           0 :     return true;
     325             : }
     326             : 
     327           0 : void AgentQosConfigTable::ReleaseIndex(AgentQosConfig *qc) {
     328           0 :     if (qc->id() != kInvalidIndex) {
     329           0 :         agent()->resource_manager()->Release(Resource::QOS_INDEX, qc->id());
     330           0 :         index_table_.Remove(qc->id());
     331             :     }
     332           0 : }
     333             : 
     334           0 : bool AgentQosConfigTable::IFNodeToReq(IFMapNode *node, DBRequest &req,
     335             :                                       const boost::uuids::uuid &u) {
     336           0 :     assert(!u.is_nil());
     337             : 
     338           0 :     if ((req.oper == DBRequest::DB_ENTRY_DELETE) || node->IsDeleted()) {
     339           0 :         req.key.reset(new AgentQosConfigKey(u));
     340           0 :         req.oper = DBRequest::DB_ENTRY_DELETE;
     341           0 :         Enqueue(&req);
     342           0 :         return false;
     343             :     }
     344             : 
     345           0 :     agent()->config_manager()->AddQosConfigNode(node);
     346           0 :     return false;
     347             : }
     348             : 
     349           0 : bool AgentQosConfigTable::IFNodeToUuid(IFMapNode *node, boost::uuids::uuid &u) {
     350           0 :     autogen::QosConfig *cfg = static_cast <autogen::QosConfig *> (node->GetObject());
     351           0 :     assert(cfg);
     352           0 :     autogen::IdPermsType id_perms = cfg->id_perms();
     353           0 :     CfgUuidSet(id_perms.uuid.uuid_mslong, id_perms.uuid.uuid_lslong, u);
     354           0 :     return true;
     355           0 : }
     356             : 
     357           0 : bool AgentQosConfigTable::ProcessConfig(IFMapNode *node, DBRequest &req,
     358             :                                         const boost::uuids::uuid &u) {
     359           0 :     if (node->IsDeleted()) {
     360           0 :         return false;
     361             :     }
     362             : 
     363           0 :     req.oper = DBRequest::DB_ENTRY_ADD_CHANGE;
     364           0 :     req.key.reset(new AgentQosConfigKey(u));
     365           0 :     req.data.reset(BuildData(node));
     366           0 :     Enqueue(&req);
     367           0 :     return false;
     368             : }
     369             : 
     370             : AgentQosConfigData*
     371           0 : AgentQosConfigTable::BuildData(IFMapNode *node) {
     372           0 :     AgentQosConfigData *qcd = new AgentQosConfigData(agent(), node);
     373           0 :     autogen::QosConfig *cfg = static_cast <autogen::QosConfig *> (node->GetObject());
     374             : 
     375             :     std::vector<QosIdForwardingClassPair>::const_iterator it =
     376           0 :         cfg->dscp_entries().begin();
     377           0 :     for(; it != cfg->dscp_entries().end(); it++) {
     378           0 :         qcd->dscp_map_[it->key] = it->forwarding_class_id;
     379             :     }
     380             : 
     381           0 :     for(it = cfg->vlan_priority_entries().begin();
     382           0 :         it != cfg->vlan_priority_entries().end(); it++) {
     383           0 :         qcd->vlan_priority_map_[it->key] = it->forwarding_class_id;
     384             :     }
     385             : 
     386           0 :     for(it = cfg->mpls_exp_entries().begin();
     387           0 :         it != cfg->mpls_exp_entries().end(); it++) {
     388           0 :         qcd->mpls_exp_map_[it->key] = it->forwarding_class_id;
     389             :     }
     390             : 
     391           0 :     qcd->name_ = node->name();
     392           0 :     if (cfg->type() == "vhost") {
     393           0 :         qcd->type_ = AgentQosConfig::VHOST;
     394           0 :     } else if (cfg->type() == "fabric") {
     395           0 :         qcd->type_ = AgentQosConfig::FABRIC;
     396             :     } else {
     397           0 :         qcd->type_ = AgentQosConfig::DEFAULT;
     398             :     }
     399             : 
     400           0 :     qcd->default_forwarding_class_ = cfg->default_forwarding_class_id();
     401             : 
     402           0 :     return qcd;
     403             : }
     404             : 
     405             : AgentSandeshPtr
     406           0 : AgentQosConfigTable::GetAgentSandesh(const AgentSandeshArguments *args,
     407             :                                      const std::string &context) {
     408             :     return AgentSandeshPtr(new AgentQosConfigSandesh(context,
     409           0 :                 args->GetString("uuid"), args->GetString("name"),
     410           0 :                 args->GetString("id")));
     411             : }
     412             : 
     413           0 : void AgentQosConfigSandeshReq::HandleRequest() const {
     414           0 :     AgentSandeshPtr sand(new AgentQosConfigSandesh(context(), get_uuid(),
     415           0 :                                                    get_name(), get_id()));
     416           0 :     sand->DoSandesh(sand);
     417           0 : }
     418             : 
     419           0 : void AddQosConfig::HandleRequest() const {
     420           0 :     QosResponse *resp = new QosResponse();
     421           0 :     resp->set_context(context());
     422             : 
     423             :     char str[50];
     424           0 :     sprintf(str, "00000000-0000-0000-0000-00%010x", get_uuid());
     425           0 :     boost::uuids::uuid u1 = StringToUuid(std::string(str));
     426             : 
     427           0 :     AgentQosConfigData *data = new AgentQosConfigData(Agent::GetInstance(), NULL);
     428             : 
     429           0 :     data->dscp_map_.insert(AgentQosIdForwardingClassPair(get_dscp(),
     430           0 :                           get_dscp_forwarding_class_id()));
     431           0 :     data->vlan_priority_map_.insert(AgentQosIdForwardingClassPair(get_vlan_priority(),
     432           0 :                              get_vlan_priority_forwarding_class_id()));
     433           0 :     data->mpls_exp_map_.insert(AgentQosIdForwardingClassPair(get_mpls_exp(),
     434           0 :                         get_mpls_exp_forwarding_class_id()));
     435           0 :     data->name_ = get_name();
     436             : 
     437           0 :     if (get_type() == "vhost") {
     438           0 :         data->type_ = AgentQosConfig::VHOST;
     439           0 :     } else if (get_type() == "fabric") {
     440           0 :         data->type_ = AgentQosConfig::FABRIC;
     441             :     } else {
     442           0 :         data->type_ = AgentQosConfig::DEFAULT;
     443             :     }
     444             : 
     445             : 
     446           0 :     DBTable *table = Agent::GetInstance()->qos_config_table();
     447           0 :     DBRequest req;
     448           0 :     req.oper = DBRequest::DB_ENTRY_ADD_CHANGE;
     449           0 :     req.key.reset(new AgentQosConfigKey(u1));
     450           0 :     req.data.reset(data);
     451           0 :     table->Enqueue(&req);
     452           0 :     resp->set_resp("Success");
     453           0 :     resp->Response();
     454           0 : }
     455             : 
     456           0 : void DeleteQosConfig::HandleRequest() const {
     457           0 :     QosResponse *resp = new QosResponse();
     458           0 :     resp->set_context(context());
     459             : 
     460             :     char str[50];
     461           0 :     sprintf(str, "00000000-0000-0000-0000-00%010x", get_uuid());
     462           0 :     boost::uuids::uuid u1 = StringToUuid(std::string(str));
     463             : 
     464           0 :     DBTable *table = Agent::GetInstance()->qos_config_table();
     465           0 :     DBRequest req;
     466           0 :     req.oper = DBRequest::DB_ENTRY_DELETE;
     467           0 :     req.key.reset(new AgentQosConfigKey(u1));
     468           0 :     req.data.reset(NULL);
     469           0 :     table->Enqueue(&req);
     470           0 :     resp->set_resp("Success");
     471           0 :     resp->Response();
     472           0 : }

Generated by: LCOV version 1.14