LCOV - code coverage report
Current view: top level - vnsw/agent/oper - bridge_domain.cc (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 11 215 5.1 %
Date: 2026-11-09 02:10:49 Functions: 4 27 14.8 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2016 Juniper Networks, Inc. All rights reserved.
       3             :  * Copyright Contributors to the OpenSDN project
       4             :  */
       5             : 
       6             : #include <cmn/agent_cmn.h>
       7             : #include <vnc_cfg_types.h>
       8             : #include <agent_types.h>
       9             : #include <init/agent_param.h>
      10             : #include <cfg/cfg_init.h>
      11             : #include <ifmap/ifmap_node.h>
      12             : #include <cmn/agent_cmn.h>
      13             : #include <oper/ifmap_dependency_manager.h>
      14             : #include <bgp_schema_types.h>
      15             : #include <oper/config_manager.h>
      16             : #include <oper/agent_sandesh.h>
      17             : #include <oper/vn.h>
      18             : #include <oper/vrf.h>
      19             : #include "oper/bridge_domain.h"
      20             : 
      21           0 : BridgeDomainEntry::BridgeDomainEntry(const BridgeDomainTable *table,
      22           0 :                                      const boost::uuids::uuid &id) :
      23           0 :     AgentOperDBEntry(), table_(table), uuid_(id), isid_(0), bmac_vrf_name_(""),
      24           0 :     learning_enabled_(false), pbb_etree_enabled_(false), layer2_control_word_(false) {
      25           0 : }
      26             : 
      27           0 : bool BridgeDomainEntry::IsLess(const DBEntry &rhs) const {
      28           0 :     const BridgeDomainEntry &bd =
      29             :         static_cast<const BridgeDomainEntry &>(rhs);
      30           0 :     return (uuid_ < bd.uuid_);
      31             : }
      32             : 
      33           0 : std::string BridgeDomainEntry::ToString() const {
      34           0 :     return UuidToString(uuid_);
      35             : }
      36             : 
      37           0 : DBEntryBase::KeyPtr BridgeDomainEntry::GetDBRequestKey() const {
      38           0 :     BridgeDomainKey *key = new BridgeDomainKey(uuid_);
      39           0 :     return DBEntryBase::KeyPtr(key);
      40             : }
      41             : 
      42           0 : void BridgeDomainEntry::SetKey(const DBRequestKey *key) {
      43           0 :     const BridgeDomainKey *k =
      44             :         static_cast<const BridgeDomainKey *>(key);
      45           0 :     uuid_ = k->uuid_;
      46           0 : }
      47             : 
      48           0 : bool BridgeDomainEntry::DBEntrySandesh(Sandesh *sresp,
      49             :                                        std::string &name) const {
      50           0 :     BridgeDomainSandeshResp *resp =
      51             :         static_cast<BridgeDomainSandeshResp *>(sresp);
      52             : 
      53           0 :     BridgeDomainSandeshData data;
      54           0 :     data.set_uuid(UuidToString(uuid_));
      55           0 :     data.set_name(name_);
      56           0 :     data.set_isid(isid_);
      57           0 :     if (vn_.get()) {
      58           0 :         data.set_vn(UuidToString(vn_->GetUuid()));
      59             :     }
      60             : 
      61           0 :     if (vrf_.get()) {
      62           0 :         data.set_vrf(vrf_->GetName());
      63             :     }
      64             : 
      65           0 :     if (learning_enabled_) {
      66           0 :         data.set_learning_enabled("True");
      67             :     } else {
      68           0 :         data.set_learning_enabled("False");
      69             :     }
      70             : 
      71           0 :     if (pbb_etree_enabled_) {
      72           0 :         data.set_pbb_etree_enabled("True");
      73             :     } else {
      74           0 :         data.set_pbb_etree_enabled("False");
      75             :     }
      76             : 
      77             :     std::vector<BridgeDomainSandeshData> &list =
      78           0 :         const_cast<std::vector<BridgeDomainSandeshData>&>(resp->get_bd_list());
      79           0 :     list.push_back(data);
      80           0 :     return true;
      81           0 : }
      82             : 
      83           0 : void BridgeDomainEntry::UpdateVrf(const BridgeDomainData *data) {
      84           0 :     std::ostringstream str;
      85           0 :     str << data->bmac_vrf_name_ << ":" << UuidToString(uuid_);
      86             : 
      87           0 :     bmac_vrf_name_ = data->bmac_vrf_name_;
      88             : 
      89           0 :     VrfKey key(str.str());
      90           0 :     vrf_ = static_cast<VrfEntry *>(table_->agent()->
      91           0 :                                    vrf_table()->Find(&key, true));
      92           0 :     if (vrf_ && vrf_->IsDeleted()) {
      93           0 :         vrf_ = NULL;
      94           0 :         return;
      95             :     }
      96             : 
      97           0 :     table_->agent()->vrf_table()->CreateVrf(str.str(), data->vn_uuid_,
      98             :                                             VrfData::PbbVrf, isid_,
      99           0 :                                             data->bmac_vrf_name_,
     100           0 :                                             data->mac_aging_time_,
     101           0 :                                             data->learning_enabled_);
     102             : 
     103           0 :     vrf_ = static_cast<VrfEntry *>(table_->agent()->vrf_table()->
     104           0 :             FindActiveEntry(&key));
     105           0 :     assert(vrf_);
     106             : 
     107           0 :     vrf_->CreateTableLabel(data->learning_enabled_, true,
     108           0 :                            vn_->flood_unknown_unicast(),
     109           0 :                            vn_->layer2_control_word());
     110           0 :     mac_aging_time_ = data->mac_aging_time_;
     111           0 :     layer2_control_word_ = vn_->layer2_control_word();
     112           0 : }
     113             : 
     114           0 : bool BridgeDomainEntry::Change(const BridgeDomainTable *table,
     115             :                                const BridgeDomainData *data) {
     116           0 :     bool ret = false;
     117           0 :     bool update_vrf = false;
     118             : 
     119           0 :     name_ = data->name_;
     120           0 :     VnEntry *vn = table_->agent()->vn_table()->Find(data->vn_uuid_);
     121           0 :     if (vn_ != vn) {
     122           0 :         vn_ = vn;
     123           0 :         update_vrf = true;
     124           0 :         ret = true;
     125             :     }
     126             : 
     127           0 :     if (isid_ != data->isid_) {
     128           0 :         isid_ = data->isid_;
     129           0 :         update_vrf = true;
     130           0 :         ret = true;
     131             :     }
     132             : 
     133           0 :     if (isid_ == 0) {
     134           0 :         OPER_TRACE_ENTRY(BridgeDomain, table,
     135             :                          "Ignoring bridge-domain update with ISID 0",
     136             :                          UuidToString(uuid_), isid_);
     137           0 :         return ret;
     138             :     }
     139             : 
     140           0 :     if (mac_aging_time_ != data->mac_aging_time_) {
     141           0 :         mac_aging_time_ = data->mac_aging_time_;
     142           0 :         update_vrf = true;
     143           0 :         ret = true;
     144             :     }
     145             : 
     146           0 :     if (learning_enabled_ != data->learning_enabled_) {
     147           0 :         learning_enabled_ = data->learning_enabled_;
     148           0 :         update_vrf = true;
     149           0 :         ret = true;
     150             :     }
     151             : 
     152           0 :     if (vn && layer2_control_word_ != vn->layer2_control_word()) {
     153           0 :         layer2_control_word_ = vn->layer2_control_word();
     154           0 :         update_vrf = true;
     155           0 :         ret = true;
     156             :     }
     157             : 
     158           0 :     if (pbb_etree_enabled_ != data->pbb_etree_enabled_) {
     159           0 :         pbb_etree_enabled_ = data->pbb_etree_enabled_;
     160           0 :         ret = true;
     161             :     }
     162             : 
     163           0 :     if (bmac_vrf_name_ != data->bmac_vrf_name_) {
     164           0 :         bmac_vrf_name_ = data->bmac_vrf_name_;
     165           0 :         update_vrf = true;
     166           0 :         ret = true;
     167             :     }
     168             : 
     169           0 :     if (vrf_ == NULL) {
     170           0 :         update_vrf = true;
     171             :     }
     172             : 
     173           0 :     if (vn_ && data->bmac_vrf_name_ != Agent::NullString() && update_vrf) {
     174           0 :         OPER_TRACE_ENTRY(BridgeDomain, table, "Creating C-VRF",
     175             :                          UuidToString(uuid_), isid_);
     176           0 :         UpdateVrf(data);
     177             :     }
     178             : 
     179           0 :     return ret;
     180             : }
     181             : 
     182           0 : void BridgeDomainEntry::Delete() {
     183           0 :     BridgeDomainTable *table = static_cast<BridgeDomainTable *>(get_table());
     184           0 :     OPER_TRACE_ENTRY(BridgeDomain, table, "Deleting bridge-domain",
     185             :                      UuidToString(uuid_), isid_);
     186           0 :     if (vrf_.get()) {
     187           0 :         table_->agent()->vrf_table()->DeleteVrf(vrf_->GetName(),
     188             :                                                 VrfData::PbbVrf);
     189           0 :         vrf_.reset();
     190             :     }
     191           0 : }
     192             : 
     193           2 : BridgeDomainTable::BridgeDomainTable(Agent *agent, DB *db,
     194           2 :                                      const std::string &name) :
     195           2 :     AgentOperDBTable(db, name) {
     196           2 :     set_agent(agent);
     197           2 : }
     198             : 
     199           4 : BridgeDomainTable::~BridgeDomainTable() {
     200           4 : }
     201             : 
     202           2 : DBTableBase *BridgeDomainTable::CreateTable(Agent *agent, DB *db,
     203             :                                             const std::string &name) {
     204           2 :     BridgeDomainTable *table = new BridgeDomainTable(agent, db, name);
     205           2 :     table->Init();
     206           2 :     return table;
     207             : }
     208             : 
     209             : std::unique_ptr<DBEntry>
     210           0 : BridgeDomainTable::AllocEntry(const DBRequestKey *k) const {
     211           0 :     const BridgeDomainKey *key = static_cast<const BridgeDomainKey *>(k);
     212           0 :     BridgeDomainEntry *bd = new BridgeDomainEntry(this, key->uuid_);
     213           0 :     return std::unique_ptr<DBEntry>(static_cast<DBEntry *>(bd));
     214             : }
     215             : 
     216           0 : DBEntry *BridgeDomainTable::OperDBAdd(const DBRequest *req) {
     217           0 :     BridgeDomainKey *key = static_cast<BridgeDomainKey *>(req->key.get());
     218           0 :     BridgeDomainData *data = static_cast<BridgeDomainData *>(req->data.get());
     219           0 :     BridgeDomainEntry *bd = new BridgeDomainEntry(this, key->uuid_);
     220           0 :     bd->Change(this, data);
     221           0 :     return bd;
     222             : }
     223             : 
     224           0 : bool BridgeDomainTable::OperDBOnChange(DBEntry *entry, const DBRequest *req) {
     225           0 :     BridgeDomainEntry *bd = static_cast<BridgeDomainEntry *>(entry);
     226           0 :     BridgeDomainData *data = dynamic_cast<BridgeDomainData *>(req->data.get());
     227           0 :     bool ret = bd->Change(this, data);
     228           0 :     return ret;
     229             : }
     230             : 
     231           0 : bool BridgeDomainTable::OperDBResync(DBEntry *entry, const DBRequest *req) {
     232           0 :     return OperDBOnChange(entry, req);
     233             : }
     234             : 
     235           0 : bool BridgeDomainTable::OperDBDelete(DBEntry *entry, const DBRequest *req) {
     236           0 :     BridgeDomainEntry *bd = static_cast<BridgeDomainEntry *>(entry);
     237           0 :     bd->Delete();
     238           0 :     return true;
     239             : }
     240             : 
     241           0 : static BridgeDomainKey *BuildKey(const boost::uuids::uuid &u) {
     242           0 :     return new BridgeDomainKey(u);
     243             : }
     244             : 
     245           0 : static void BuildVrfData (Agent *agent, IFMapNode *vn_node,
     246             :                           BridgeDomainData *data) {
     247           0 :     IFMapAgentTable *table = static_cast<IFMapAgentTable *>(vn_node->table());
     248           0 :     DBGraph *graph = table->GetGraph();
     249             : 
     250           0 :     for (DBGraphVertex::adjacency_iterator iter = vn_node->begin(graph);
     251           0 :             iter != vn_node->end(table->GetGraph()); ++iter) {
     252             : 
     253           0 :         IFMapNode *adj_node = static_cast<IFMapNode *>(iter.operator->());
     254           0 :         if (agent->config_manager()->SkipNode(adj_node)) {
     255           0 :             continue;
     256             :         }
     257             : 
     258           0 :         if (adj_node->table() == agent->cfg()->cfg_vrf_table()) {
     259             :             autogen::RoutingInstance *vrf =
     260           0 :                 static_cast<autogen::RoutingInstance *>(adj_node->GetObject());
     261           0 :             if(vrf->is_default()) {
     262           0 :                 data->bmac_vrf_name_ = adj_node->name();
     263             :             }
     264             :         }
     265             :     }
     266           0 : }
     267             : 
     268           0 : static BridgeDomainData *BuildData(Agent *agent, IFMapNode *node,
     269             :                                    const autogen::BridgeDomain *bd) {
     270           0 :     IFMapAgentTable *table = static_cast<IFMapAgentTable *>(node->table());
     271           0 :     DBGraph *graph = table->GetGraph();
     272           0 :     boost::uuids::uuid vn_uuid = boost::uuids::nil_uuid();
     273           0 :     BridgeDomainData *bdd = new BridgeDomainData(agent, node);
     274             : 
     275           0 :     for (DBGraphVertex::adjacency_iterator iter = node->begin(graph);
     276           0 :             iter != node->end(table->GetGraph()); ++iter) {
     277             : 
     278           0 :         IFMapNode *adj_node = static_cast<IFMapNode *>(iter.operator->());
     279           0 :         if (agent->config_manager()->SkipNode(adj_node)) {
     280           0 :             continue;
     281             :         }
     282             : 
     283           0 :         if (adj_node->table() == agent->cfg()->cfg_vn_table()) {
     284             :             autogen::VirtualNetwork *vn =
     285           0 :                 static_cast<autogen::VirtualNetwork *>(adj_node->GetObject());
     286           0 :             autogen::IdPermsType id_perms = vn->id_perms();
     287           0 :             CfgUuidSet(id_perms.uuid.uuid_mslong, id_perms.uuid.uuid_lslong,
     288             :                        vn_uuid);
     289           0 :             bdd->pbb_etree_enabled_ = vn->pbb_etree_enable();
     290           0 :             BuildVrfData(agent, adj_node, bdd);
     291           0 :         }
     292             :     }
     293             : 
     294           0 :     bdd->name_ = node->name();
     295           0 :     bdd->isid_ = bd->isid();
     296           0 :     bdd->vn_uuid_ = vn_uuid;
     297           0 :     bdd->learning_enabled_ = bd->mac_learning_enabled();
     298           0 :     bdd->mac_aging_time_ = bd->mac_aging_time();
     299           0 :     return bdd;
     300             : }
     301             : 
     302           0 : bool BridgeDomainTable::IFNodeToReq(IFMapNode *node, DBRequest &req,
     303             :                                     const boost::uuids::uuid &u) {
     304             :     autogen::BridgeDomain *bd =
     305           0 :         static_cast<autogen::BridgeDomain *>(node->GetObject());
     306           0 :     assert(bd);
     307             : 
     308           0 :     assert(!u.is_nil());
     309             : 
     310           0 :     req.key.reset(BuildKey(u));
     311           0 :     if ((req.oper == DBRequest::DB_ENTRY_DELETE) || node->IsDeleted()) {
     312           0 :         req.oper = DBRequest::DB_ENTRY_DELETE;
     313           0 :         return true;
     314             :     }
     315             : 
     316           0 :     agent()->config_manager()->AddBridgeDomainNode(node);
     317           0 :     return false;
     318             : }
     319             : 
     320           0 : bool BridgeDomainTable::ProcessConfig(IFMapNode *node, DBRequest &req,
     321             :                                      const boost::uuids::uuid &u) {
     322             :     autogen::BridgeDomain *bd =
     323           0 :         static_cast <autogen::BridgeDomain *>(node->GetObject());
     324           0 :     assert(bd);
     325             : 
     326           0 :     req.key.reset(BuildKey(u));
     327           0 :     if (node->IsDeleted()) {
     328           0 :         return false;
     329             :     }
     330             : 
     331           0 :     req.oper = DBRequest::DB_ENTRY_ADD_CHANGE;
     332           0 :     req.data.reset(BuildData(agent(), node, bd));
     333           0 :     return true;
     334             : }
     335             : 
     336           0 : bool BridgeDomainTable::IFNodeToUuid(IFMapNode *node, boost::uuids::uuid &u) {
     337             :     autogen::BridgeDomain *bd =
     338           0 :         static_cast<autogen::BridgeDomain *>(node->GetObject());
     339           0 :     autogen::IdPermsType id_perms = bd->id_perms();
     340           0 :     CfgUuidSet(id_perms.uuid.uuid_mslong, id_perms.uuid.uuid_lslong, u);
     341           0 :     return true;
     342           0 : }
     343             : 
     344           0 : BridgeDomainEntry *BridgeDomainTable::Find(const boost::uuids::uuid &u) {
     345           0 :     BridgeDomainKey key(u);
     346           0 :     return static_cast<BridgeDomainEntry *>(FindActiveEntry(&key));
     347           0 : }
     348             : 
     349             : AgentSandeshPtr
     350           0 : BridgeDomainTable::GetAgentSandesh(const AgentSandeshArguments *args,
     351             :                                    const std::string &context) {
     352             :     return AgentSandeshPtr(new BridgeDomainSandesh(context,
     353           0 :                                                    args->GetString("uuid"),
     354           0 :                                                    args->GetString("name")));
     355             : }
     356             : 
     357           0 : void BridgeDomainSandeshReq::HandleRequest() const {
     358           0 :     AgentSandeshPtr sand(new BridgeDomainSandesh(context(), get_uuid(),
     359           0 :                                                  get_name()));
     360           0 :     sand->DoSandesh(sand);
     361           0 : }

Generated by: LCOV version 1.14