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

Generated by: LCOV version 1.14