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

Generated by: LCOV version 1.14