LCOV - code coverage report
Current view: top level - vnsw/agent/uve - vrouter_uve_entry_base.cc (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 148 624 23.7 %
Date: 2026-11-09 02:10:49 Functions: 10 33 30.3 %
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 <sstream>
       7             : #include <fstream>
       8             : #include <sandesh/common/vns_types.h>
       9             : #include <uve/vrouter_uve_entry.h>
      10             : #include <cfg/cfg_init.h>
      11             : #include <init/agent_param.h>
      12             : #include <oper/interface_common.h>
      13             : #include <oper/interface.h>
      14             : #include <oper/vm.h>
      15             : #include <oper/vn.h>
      16             : #include <oper/mirror_table.h>
      17             : #include <controller/controller_peer.h>
      18             : #include <uve/agent_uve_base.h>
      19             : #include <cmn/agent_stats.h>
      20             : #include <base/cpuinfo.h>
      21             : #include <base/util.h>
      22             : #include <cmn/agent_cmn.h>
      23             : #include <oper/operdb_init.h>
      24             : #include <oper/bgp_as_service.h>
      25             : 
      26             : using namespace std;
      27             : 
      28             : extern const std::string BuildInfo;
      29             : 
      30           4 : VrouterUveEntryBase::VrouterUveEntryBase(Agent *agent)
      31           4 :     : agent_(agent), phy_intf_set_(), prev_stats_(), prev_vrouter_(),
      32           4 :       cpu_stats_count_(0), do_vn_walk_(false), do_vm_walk_(false),
      33           4 :       do_interface_walk_(false), vn_walk_ref_(NULL), vm_walk_ref_(NULL),
      34           4 :       interface_walk_ref_(NULL), vn_listener_id_(DBTableBase::kInvalidId),
      35           4 :       vm_listener_id_(DBTableBase::kInvalidId),
      36           4 :       intf_listener_id_(DBTableBase::kInvalidId),
      37           4 :       physical_device_listener_id_(DBTableBase::kInvalidId),
      38           8 :       timer_(TimerManager::CreateTimer(
      39           4 :                  *(agent_->event_manager())->io_service(), "UveDBWalkTimer",
      40           4 :                  TaskScheduler::GetInstance()->GetTaskId(kTaskDBExclude), 0)) {
      41           4 :     StartTimer();
      42             : 
      43           4 : }
      44             : 
      45           4 : VrouterUveEntryBase::~VrouterUveEntryBase() {
      46           4 : }
      47             : 
      48           4 : void VrouterUveEntryBase::StartTimer() {
      49           4 :     timer_->Cancel();
      50           4 :     uint32_t tm_interval = AgentUveBase::kDefaultInterval;
      51           4 :     if (agent_ != nullptr && agent_->uve() != nullptr) {
      52           0 :         tm_interval = agent_->uve()->default_interval();
      53             :     }
      54           4 :     timer_->Start(tm_interval,
      55             :                   boost::bind(&VrouterUveEntryBase::TimerExpiry, this));
      56           4 : }
      57             : 
      58           0 : bool VrouterUveEntryBase::TimerExpiry() {
      59           0 :     bool restart = Run();
      60           0 :     return restart;
      61             : }
      62             : 
      63           0 : bool VrouterUveEntryBase::Run() {
      64             :     /* We don't do vn, vm and interface walks simultaneously to avoid creation
      65             :      * of multiple threads (caused by start of walks). After all the walks are
      66             :      * done we re-start the timer */
      67           0 :     bool walk_started = StartVnWalk();
      68             : 
      69             :     /* If VN walk is not started, start VM walk */
      70           0 :     if (!walk_started) {
      71           0 :         walk_started = StartVmWalk();
      72             : 
      73             :         /* If neither VN nor VM walks have started, start interface walk */
      74           0 :         if (!walk_started) {
      75           0 :             walk_started = StartInterfaceWalk();
      76             : 
      77             :             /* If none of the walks are started, return true to trigger
      78             :              * auto restart of timer */
      79           0 :             if (!walk_started) {
      80           0 :                 return true;
      81             :             }
      82             :         }
      83             :     }
      84             : 
      85           0 :     return false;
      86             : }
      87             : 
      88           2 : void VrouterUveEntryBase::PhysicalDeviceNotify(DBTablePartBase *partition,
      89             :                                                DBEntryBase *e) {
      90           2 :     const PhysicalDevice *pr = static_cast<const PhysicalDevice *>(e);
      91             :     VrouterPhysicalDeviceState *state = static_cast<VrouterPhysicalDeviceState *>
      92           2 :         (e->GetState(partition->parent(), physical_device_listener_id_));
      93           2 :     if (e->IsDeleted()) {
      94           1 :         if (state) {
      95           1 :             e->ClearState(partition->parent(), physical_device_listener_id_);
      96           1 :             delete state;
      97             :         }
      98             :     } else {
      99           1 :         if (!state) {
     100           1 :             state = new VrouterPhysicalDeviceState();
     101           1 :             e->SetState(partition->parent(), physical_device_listener_id_,
     102             :                         state);
     103           1 :             do_interface_walk_ = true;
     104             :         } else {
     105           0 :             if (state->master_ != pr->master()) {
     106           0 :                 do_interface_walk_ = true;
     107             :             }
     108             :         }
     109           1 :         state->master_ = pr->master();
     110             :     }
     111           2 : }
     112             : 
     113           2 : void VrouterUveEntryBase::RegisterDBClients() {
     114           2 :     VnTable *vn_table = agent_->vn_table();
     115           2 :     vn_listener_id_ = vn_table->Register
     116           2 :                   (boost::bind(&VrouterUveEntryBase::VnNotify, this, _1, _2));
     117             : 
     118           2 :     VmTable *vm_table = agent_->vm_table();
     119           2 :     vm_listener_id_ = vm_table->Register
     120           2 :         (boost::bind(&VrouterUveEntryBase::VmNotify, this, _1, _2));
     121             : 
     122           2 :     InterfaceTable *intf_table = agent_->interface_table();
     123           2 :     intf_listener_id_ = intf_table->Register
     124           2 :         (boost::bind(&VrouterUveEntryBase::InterfaceNotify, this, _1, _2));
     125             : 
     126           2 :     PhysicalDeviceTable *pd_table = agent_->physical_device_table();
     127           2 :     physical_device_listener_id_ = pd_table->Register
     128           2 :         (boost::bind(&VrouterUveEntryBase::PhysicalDeviceNotify, this, _1, _2));
     129           2 : }
     130             : 
     131           4 : void VrouterUveEntryBase::Shutdown(void) {
     132           4 :     if (physical_device_listener_id_ != DBTableBase::kInvalidId)
     133           2 :         agent_->physical_device_table()->
     134           2 :             Unregister(physical_device_listener_id_);
     135           4 :     if (intf_listener_id_ != DBTableBase::kInvalidId)
     136           2 :         agent_->interface_table()->Unregister(intf_listener_id_);
     137           4 :     if (vm_listener_id_ != DBTableBase::kInvalidId)
     138           2 :         agent_->vm_table()->Unregister(vm_listener_id_);
     139           4 :     if (vn_listener_id_ != DBTableBase::kInvalidId)
     140           2 :         agent_->vn_table()->Unregister(vn_listener_id_);
     141           4 :     if (interface_walk_ref_.get() != NULL)
     142           0 :         agent_->interface_table()->ReleaseWalker(interface_walk_ref_);
     143           4 :     if (vn_walk_ref_.get() != NULL)
     144           0 :         agent_->vn_table()->ReleaseWalker(vn_walk_ref_);
     145           4 :     if (vm_walk_ref_.get() != NULL)
     146           0 :         agent_->vm_table()->ReleaseWalker(vm_walk_ref_);
     147           4 :     if (timer_) {
     148           4 :         timer_->Cancel();
     149           4 :         TimerManager::DeleteTimer(timer_);
     150           4 :         timer_ = NULL;
     151             :     }
     152           4 :     vn_walk_ref_ = NULL;
     153           4 :     vm_walk_ref_ = NULL;
     154           4 :     interface_walk_ref_ = NULL;
     155           4 : }
     156             : 
     157           0 : void VrouterUveEntryBase::DispatchVrouterMsg(const VrouterAgent &uve) {
     158           0 :     UveVrouterAgent::Send(uve);
     159           0 : }
     160             : 
     161           0 : void VrouterUveEntryBase::VmWalkDone(DBTableBase *base, StringVectorPtr list) {
     162           0 :     VrouterAgent vrouter_agent;
     163           0 :     vrouter_agent.set_name(agent_->agent_name());
     164           0 :     vrouter_agent.set_virtual_machine_list(*(list.get()));
     165           0 :     VrouterAgentObjectCount vm_count;
     166           0 :     vm_count.set_active(list.get()->size());
     167           0 :     vrouter_agent.set_vm_count(vm_count);
     168           0 :     DispatchVrouterMsg(vrouter_agent);
     169             : 
     170             :     /* Start Interface Walk after we are done with Vm Walk */
     171           0 :     bool walk_started = StartInterfaceWalk();
     172             : 
     173             :     /* If interface walk has not started, restart the timer */
     174           0 :     if (!walk_started) {
     175           0 :         StartTimer();
     176             :     }
     177           0 :     (*list).clear();
     178           0 : }
     179             : 
     180           0 : bool VrouterUveEntryBase::AppendVm(DBTablePartBase *part, DBEntryBase *entry,
     181             :                                StringVectorPtr list) {
     182           0 :     VmEntry *vm = static_cast<VmEntry *>(entry);
     183             : 
     184           0 :     if (!vm->IsDeleted()) {
     185           0 :         std::ostringstream ostr;
     186           0 :         ostr << vm->GetUuid();
     187           0 :         list.get()->push_back(ostr.str());
     188           0 :     }
     189           0 :     return true;
     190             : }
     191             : 
     192           0 : bool VrouterUveEntryBase::StartVmWalk() {
     193           0 :     if (!do_vm_walk_) {
     194             :         /* There is no change in VM list. No need of walk */
     195           0 :         return false;
     196             :     }
     197           0 :     if (vm_walk_ref_.get() == NULL) {
     198           0 :         StringVectorPtr vm_list(new vector<string>());
     199           0 :         vm_walk_ref_ = agent_->vm_table()->AllocWalker(
     200           0 :            boost::bind(&VrouterUveEntryBase::AppendVm, this, _1, _2, vm_list),
     201           0 :            boost::bind(&VrouterUveEntryBase::VmWalkDone, this, _2, vm_list));
     202           0 :     }
     203           0 :     agent_->vm_table()->WalkAgain(vm_walk_ref_);
     204           0 :     do_vm_walk_ = false;
     205           0 :     return true;
     206             : }
     207             : 
     208         330 : void VrouterUveEntryBase::VmNotify(DBTablePartBase *partition, DBEntryBase *e) {
     209             :     DBState *state = static_cast<DBState *>
     210         330 :         (e->GetState(partition->parent(), vm_listener_id_));
     211             : 
     212         330 :     if (e->IsDeleted()) {
     213         165 :         if (state) {
     214         165 :             do_vm_walk_ = true;
     215         165 :             e->ClearState(partition->parent(), vm_listener_id_);
     216         165 :             delete state;
     217             :         }
     218         165 :         return;
     219             :     }
     220             : 
     221         165 :     if (!state) {
     222         165 :         state = new DBState();
     223         165 :         e->SetState(partition->parent(), vm_listener_id_, state);
     224             :         //Send vrouter object only for a add/delete
     225         165 :         do_vm_walk_ = true;
     226             :     }
     227             : }
     228             : 
     229           0 : void VrouterUveEntryBase::VnWalkDone(DBTableBase *base, StringVectorPtr list) {
     230           0 :     VrouterAgent vrouter_agent;
     231           0 :     vrouter_agent.set_name(agent_->agent_name());
     232           0 :     vrouter_agent.set_connected_networks(*(list.get()));
     233           0 :     vrouter_agent.set_vn_count((*list).size());
     234           0 :     DispatchVrouterMsg(vrouter_agent);
     235             : 
     236             :     //Update prev_vrouter_ fields. Currently used only in UT
     237           0 :     prev_vrouter_.set_connected_networks(*(list.get()));
     238           0 :     prev_vrouter_.set_vn_count((*list).size());
     239             : 
     240             :     /* Start Vm Walk after we are done with Vn Walk */
     241           0 :     bool walk_started = StartVmWalk();
     242             : 
     243             :     /* If VM walk has not started, start interface walk */
     244           0 :     if (!walk_started) {
     245           0 :         walk_started = StartInterfaceWalk();
     246             : 
     247             :         /* If interface walk has not started, restart the timer */
     248           0 :         if (!walk_started) {
     249           0 :             StartTimer();
     250             :         }
     251             :     }
     252           0 :     (*list).clear();
     253           0 : }
     254             : 
     255           0 : bool VrouterUveEntryBase::AppendVn(DBTablePartBase *part, DBEntryBase *entry,
     256             :                                StringVectorPtr list) {
     257           0 :     VnEntry *vn = static_cast<VnEntry *>(entry);
     258             : 
     259           0 :     if (!vn->IsDeleted()) {
     260           0 :         list.get()->push_back(vn->GetName());
     261             :     }
     262           0 :     return true;
     263             : }
     264             : 
     265           0 : bool VrouterUveEntryBase::StartVnWalk() {
     266           0 :     if (!do_vn_walk_) {
     267             :         /* There is no change in VN list. No need of walk */
     268           0 :         return false;
     269             :     }
     270           0 :     if (vn_walk_ref_.get() == NULL) {
     271           0 :         StringVectorPtr vn_list(new vector<string>());
     272           0 :         vn_walk_ref_ = agent_->vn_table()->AllocWalker(
     273           0 :            boost::bind(&VrouterUveEntryBase::AppendVn, this, _1, _2, vn_list),
     274           0 :            boost::bind(&VrouterUveEntryBase::VnWalkDone, this, _2, vn_list));
     275             : 
     276           0 :     }
     277           0 :     agent_->vn_table()->WalkAgain(vn_walk_ref_);
     278           0 :     do_vn_walk_ = false;
     279           0 :     return true;
     280             : }
     281             : 
     282         269 : void VrouterUveEntryBase::VnNotify(DBTablePartBase *partition, DBEntryBase *e) {
     283             :     DBState *state = static_cast<DBState *>
     284         269 :         (e->GetState(partition->parent(), vn_listener_id_));
     285             : 
     286         269 :     if (e->IsDeleted()) {
     287          69 :         if (state) {
     288          69 :             do_vn_walk_ = true;
     289          69 :             e->ClearState(partition->parent(), vn_listener_id_);
     290          69 :             delete state;
     291             :         }
     292          69 :         return;
     293             :     }
     294             : 
     295         200 :     if (!state) {
     296          69 :         state = new DBState();
     297          69 :         e->SetState(partition->parent(), vn_listener_id_, state);
     298          69 :         do_vn_walk_ = true;
     299             :     }
     300             : }
     301             : 
     302           0 : void VrouterUveEntryBase::InterfaceWalkDone(DBTableBase *base,
     303             :                                         StringVectorPtr if_list,
     304             :                                         StringVectorPtr err_if_list,
     305             :                                         StringVectorPtr nova_if_list,
     306             :                                         StringVectorPtr unmanaged_list) {
     307           0 :     VrouterAgent vrouter_agent;
     308           0 :     vrouter_agent.set_name(agent_->agent_name());
     309           0 :     vrouter_agent.set_interface_list(*(if_list.get()));
     310           0 :     vrouter_agent.set_error_intf_list(*(err_if_list.get()));
     311           0 :     vrouter_agent.set_no_config_intf_list(*(nova_if_list.get()));
     312           0 :     if (agent_->tsn_enabled()) {
     313           0 :         vrouter_agent.set_unmanaged_if_list(*(unmanaged_list.get()));
     314           0 :         prev_vrouter_.set_unmanaged_if_list(*(unmanaged_list.get()));
     315             :     }
     316             : 
     317           0 :     VrouterAgentObjectCount vmi_count;
     318           0 :     vmi_count.set_active((if_list.get()->size() + nova_if_list.get()->size()));
     319           0 :     vrouter_agent.set_vmi_count(vmi_count);
     320           0 :     vrouter_agent.set_down_interface_count((err_if_list.get()->size() +
     321           0 :                                             nova_if_list.get()->size()));
     322           0 :     DispatchVrouterMsg(vrouter_agent);
     323             : 
     324             :     //Update prev_vrouter_ fields. This is being used now only for UT
     325           0 :     prev_vrouter_.set_interface_list(*(if_list.get()));
     326           0 :     prev_vrouter_.set_error_intf_list(*(err_if_list.get()));
     327           0 :     prev_vrouter_.set_no_config_intf_list(*(nova_if_list.get()));
     328             : 
     329           0 :     (*if_list).clear();
     330           0 :     (*err_if_list).clear();
     331           0 :     (*nova_if_list).clear();
     332           0 :     (*unmanaged_list).clear();
     333             :     /* Restart the timer after we are done with the walk */
     334           0 :     StartTimer();
     335           0 : }
     336             : 
     337           0 : bool VrouterUveEntryBase::AppendInterface(DBTablePartBase *part,
     338             :                                       DBEntryBase *entry,
     339             :                                       StringVectorPtr intf_list,
     340             :                                       StringVectorPtr err_if_list,
     341             :                                       StringVectorPtr nova_if_list,
     342             :                                       StringVectorPtr unmanaged_list) {
     343           0 :     Interface *intf = static_cast<Interface *>(entry);
     344             : 
     345           0 :     if (intf->type() == Interface::VM_INTERFACE) {
     346           0 :         const VmInterface *port = static_cast<const VmInterface *>(intf);
     347           0 :         if (!entry->IsDeleted()) {
     348           0 :             if (port->cfg_name() == agent_->NullString()) {
     349           0 :                 nova_if_list.get()->push_back(UuidToString(port->GetUuid()));
     350             :             } else {
     351           0 :                 if (agent_->tsn_enabled()) {
     352             :                     /* For TSN nodes send VMI in interface_list if the VMI's
     353             :                      * physical device has tsn_enabled set to true. Otherwise
     354             :                      * send the VMI in unmanaged_list */
     355           0 :                     PhysicalDevice *pd = VmiToPhysicalDevice(port);
     356           0 :                     if (!pd || !pd->master()) {
     357           0 :                         unmanaged_list.get()->push_back(port->cfg_name());
     358           0 :                         return true;
     359             :                     }
     360           0 :                     AppendInterfaceInternal(port, intf_list, err_if_list);
     361             :                 } else {
     362           0 :                     AppendInterfaceInternal(port, intf_list, err_if_list);
     363             :                 }
     364             :             }
     365             :         }
     366             :     }
     367           0 :     else if (intf->type() == Interface::PHYSICAL) {
     368           0 :         const PhysicalInterface *phy_intf = static_cast<const
     369             :             PhysicalInterface *>(intf);
     370           0 :         if (phy_intf) {
     371             :             PhysicalInterface::BondChildIntfMap bond_childIntf_map =
     372           0 :                 phy_intf->getBondChildIntfMap();
     373             :             PhysicalInterface::BondChildIntfMapIterator it =
     374           0 :                 bond_childIntf_map.begin();
     375           0 :             for(; it != bond_childIntf_map.end(); it++) {
     376           0 :                 PhysicalInterface::Bond_ChildIntf bond_intf;
     377           0 :                 bond_intf = it->second;
     378           0 :                 if(!bond_intf.intf_status) {
     379           0 :                     err_if_list.get()->push_back(it->first);
     380             :                 }
     381           0 :             }
     382           0 :         }
     383             :     }
     384           0 :     return true;
     385             : }
     386             : 
     387           0 : void VrouterUveEntryBase::AppendInterfaceInternal(const VmInterface *port,
     388             :                                                   StringVectorPtr intf_list,
     389             :                                                   StringVectorPtr err_if_list) {
     390           0 :     intf_list.get()->push_back(port->cfg_name());
     391           0 :     if (!port->IsUveActive()) {
     392           0 :         err_if_list.get()->push_back(port->cfg_name());
     393             :     }
     394           0 : }
     395             : 
     396           0 : PhysicalDevice *VrouterUveEntryBase::VmiToPhysicalDevice
     397             :     (const VmInterface *port) {
     398           0 :     const boost::uuids::uuid u = port->logical_interface();
     399           0 :     if (u == boost::uuids::nil_uuid()) {
     400           0 :         return NULL;
     401             :     }
     402             :     LogicalInterface *intf;
     403           0 :     VlanLogicalInterfaceKey key(u, "");
     404           0 :     intf = static_cast<LogicalInterface *>
     405           0 :         (agent_->interface_table()->FindActiveEntry(&key));
     406           0 :     if (!intf || !intf->physical_interface()) {
     407           0 :         return NULL;
     408             :     }
     409           0 :     return InterfaceToPhysicalDevice(intf->physical_interface());
     410           0 : }
     411             : 
     412           0 : PhysicalDevice *VrouterUveEntryBase::InterfaceToPhysicalDevice(Interface *intf) {
     413           0 :     PhysicalDevice *pde = NULL;
     414             :     const RemotePhysicalInterface *rpintf;
     415             :     const PhysicalInterface *pintf;
     416           0 :     if (intf->type() == Interface::REMOTE_PHYSICAL) {
     417           0 :         rpintf = static_cast<const RemotePhysicalInterface *>(intf);
     418           0 :         pde = rpintf->physical_device();
     419           0 :     } else if (intf->type() == Interface::PHYSICAL) {
     420           0 :         pintf = static_cast<const PhysicalInterface *>(intf);
     421           0 :         pde = pintf->physical_device();
     422             :     }
     423           0 :     return pde;
     424             : }
     425             : 
     426           0 : bool VrouterUveEntryBase::StartInterfaceWalk() {
     427           0 :     if (!do_interface_walk_) {
     428             :         /* There is no change in interface list. No need of walk */
     429           0 :         return false;
     430             :     }
     431           0 :     if (interface_walk_ref_.get() == NULL) {
     432           0 :         StringVectorPtr intf_list(new std::vector<std::string>());
     433           0 :         StringVectorPtr err_if_list(new std::vector<std::string>());
     434           0 :         StringVectorPtr nova_if_list(new std::vector<std::string>());
     435           0 :         StringVectorPtr unmanaged_list(new std::vector<std::string>());
     436             : 
     437           0 :         interface_walk_ref_ = agent_->interface_table()->AllocWalker(
     438           0 :         boost::bind(&VrouterUveEntryBase::AppendInterface, this, _1, _2,
     439             :                          intf_list, err_if_list, nova_if_list, unmanaged_list),
     440           0 :         boost::bind(&VrouterUveEntryBase::InterfaceWalkDone, this, _2,
     441           0 :                     intf_list, err_if_list, nova_if_list, unmanaged_list));
     442           0 : }
     443           0 :     agent_->interface_table()->WalkAgain(interface_walk_ref_);
     444           0 :     do_interface_walk_ = false;
     445           0 :     return true;
     446             : }
     447             : 
     448        1421 : void VrouterUveEntryBase::InterfaceNotify(DBTablePartBase *partition,
     449             :                                           DBEntryBase *e) {
     450        1421 :     const Interface *intf = static_cast<const Interface *>(e);
     451        1421 :     bool set_state = false, reset_state = false;
     452             : 
     453             :     VrouterUveInterfaceState *state = static_cast<VrouterUveInterfaceState *>
     454        1421 :                       (e->GetState(partition->parent(), intf_listener_id_));
     455        1421 :     bool vmport_active = false;
     456        1421 :     const VmInterface *vm_port = NULL;
     457        1421 :     switch(intf->type()) {
     458        1400 :     case Interface::VM_INTERFACE:
     459        1400 :         vm_port = static_cast<const VmInterface*>(intf);
     460        1400 :         if (!e->IsDeleted() && !state) {
     461         169 :             set_state = true;
     462         169 :             vmport_active = vm_port->IsUveActive();
     463         169 :             do_interface_walk_ = true;
     464        1231 :         } else if (e->IsDeleted()) {
     465         169 :             if (state) {
     466         169 :                 reset_state = true;
     467         169 :                 do_interface_walk_ = true;
     468             :             }
     469             :         } else {
     470        1062 :             if (state && vm_port->IsUveActive() != state->vmport_active_) {
     471         167 :                 do_interface_walk_ = true;
     472         167 :                 state->vmport_active_ = vm_port->IsUveActive();
     473             :             }
     474             :         }
     475        1400 :         break;
     476           7 :     case Interface::PHYSICAL:
     477           7 :         if (e->IsDeleted()) {
     478           3 :             if (state) {
     479           2 :                 reset_state = true;
     480           2 :                 phy_intf_set_.erase(intf);
     481             :             }
     482             :         } else {
     483           4 :             const PhysicalInterface* phy_if =
     484             :                 static_cast<const PhysicalInterface*>(intf);
     485             :             /* Ignore PhysicalInterface notifications if it is not of subtype
     486             :              * FABRIC */
     487           4 :             if (phy_if->subtype() != PhysicalInterface::FABRIC) {
     488           2 :                 return;
     489             :             }
     490           2 :             if (!state) {
     491           2 :                 set_state = true;
     492           2 :                 phy_intf_set_.insert(intf);
     493             :             }
     494           2 :             if (phy_if) {
     495             :                 PhysicalInterface::BondChildIntfMap bond_childIntf_map =
     496           2 :                     phy_if->getBondChildIntfMap();
     497             :                 PhysicalInterface::BondChildIntfMapIterator it =
     498           2 :                     bond_childIntf_map.begin();
     499           2 :                 for(; it != bond_childIntf_map.end(); it++) {
     500           0 :                     PhysicalInterface::Bond_ChildIntf bond_intf;
     501           0 :                     bond_intf = it->second;
     502           0 :                     if(!bond_intf.intf_status) {
     503           0 :                         do_interface_walk_ = true;
     504             :                     }
     505             :                     else {
     506             :                         std::vector<std::string> prev_err_if_list =
     507           0 :                             prev_vrouter_.get_error_intf_list();
     508           0 :                         if (std::find(prev_err_if_list.begin(),
     509           0 :                                  prev_err_if_list.end(), it->first)
     510           0 :                                  != prev_err_if_list.end()) {
     511           0 :                              do_interface_walk_ = true;
     512             :                          }
     513           0 :                     }
     514           0 :                 }
     515           2 :             }
     516             :         }
     517           5 :         break;
     518          14 :     default:
     519          14 :         break;
     520             :     }
     521        1419 :     if (set_state) {
     522         171 :         state = new VrouterUveInterfaceState(vmport_active);
     523         171 :         e->SetState(partition->parent(), intf_listener_id_, state);
     524        1248 :     } else if (reset_state) {
     525         171 :         e->ClearState(partition->parent(), intf_listener_id_);
     526         171 :         delete state;
     527             :     }
     528        1419 :     return;
     529             : }
     530             : 
     531           0 : void VrouterUveEntryBase::SubnetToStringList
     532             :     (VirtualGatewayConfig::SubnetList &source_list, vector<string> &target_list) {
     533             :     VirtualGatewayConfig::SubnetList::iterator subnet_it =
     534           0 :         source_list.begin();
     535           0 :     while (subnet_it != source_list.end()) {
     536           0 :         string subnet_str = subnet_it->ip_.to_string() + "/" +
     537           0 :             integerToString(subnet_it->plen_);
     538           0 :         target_list.push_back(subnet_str);
     539           0 :         ++subnet_it;
     540           0 :     }
     541           0 : }
     542             : 
     543           0 : void VrouterUveEntryBase::BuildAgentConfig(VrouterAgent &vrouter_agent) {
     544           0 :     AgentVhostConfig vhost_cfg;
     545           0 :     AgentXenConfig xen_cfg;
     546           0 :     AgentVmwareConfig vmware_cfg;
     547           0 :     string hypervisor;
     548           0 :     vector<AgentVgwConfig> gw_cfg_list;
     549             : 
     550           0 :     AgentParam *param = agent_->params();
     551             : 
     552           0 :     vrouter_agent.set_log_file(param->log_file());
     553           0 :     vrouter_agent.set_config_file(param->config_file());
     554           0 :     vrouter_agent.set_log_local(param->log_local());
     555           0 :     vrouter_agent.set_log_flow(param->log_flow());
     556           0 :     vrouter_agent.set_log_category(param->log_category());
     557           0 :     vrouter_agent.set_log_level(param->log_level());
     558           0 :     vrouter_agent.set_sandesh_http_port(param->http_server_port());
     559           0 :     vrouter_agent.set_tunnel_type(param->tunnel_type());
     560           0 :     vrouter_agent.set_hostname_cfg(param->host_name());
     561           0 :     vrouter_agent.set_flow_cache_timeout_cfg(param->flow_cache_timeout());
     562             : 
     563           0 :     vrouter_agent.set_dns_server_list_cfg(param->dns_server_list());
     564           0 :     vrouter_agent.set_control_node_list_cfg(param->controller_server_list());
     565             : 
     566           0 :     vrouter_agent.set_ll_max_system_flows_cfg(param->linklocal_system_flows());
     567           0 :     vrouter_agent.set_ll_max_vm_flows_cfg(param->linklocal_vm_flows());
     568           0 :     vrouter_agent.set_control_ip(param->mgmt_ip().to_string());
     569             : 
     570           0 :     vhost_cfg.set_name(param->vhost_name());
     571           0 :     if (agent_->is_l3mh() == false) {
     572           0 :         vhost_cfg.set_ip(param->vhost_addr().to_string());
     573           0 :         vhost_cfg.set_ip_prefix_len(param->vhost_plen());
     574           0 :         if (param->gateway_list().empty() == false) {
     575           0 :             vhost_cfg.set_gateway(param->gateway_list()[0].to_string());
     576             :         }
     577             :     }
     578           0 :     vrouter_agent.set_vhost_cfg(vhost_cfg);
     579             : 
     580           0 :     vrouter_agent.set_eth_name(param->eth_port_list());
     581             : 
     582           0 :     if (param->isKvmMode()) {
     583           0 :         hypervisor = "kvm";
     584           0 :     } else if (param->isXenMode()) {
     585           0 :         hypervisor = "xen";
     586           0 :         xen_cfg.set_xen_ll_port(param->xen_ll_name());
     587           0 :         xen_cfg.set_xen_ll_ip(param->xen_ll_addr().to_string());
     588           0 :         xen_cfg.set_xen_ll_prefix_len(param->xen_ll_plen());
     589           0 :         vrouter_agent.set_xen_cfg(xen_cfg);
     590           0 :     } else if (param->isVmwareMode()) {
     591           0 :         hypervisor = "vmware";
     592           0 :         vmware_cfg.set_vmware_port(param->vmware_physical_port());
     593           0 :         vrouter_agent.set_vmware_cfg(vmware_cfg);
     594             :     }
     595           0 :     vrouter_agent.set_hypervisor(hypervisor);
     596             : 
     597           0 :     VirtualGatewayConfigTable *table = param->vgw_config_table();
     598           0 :     VirtualGatewayConfigTable::Table::iterator it = table->table().begin();
     599           0 :     while (it != table->table().end()) {
     600           0 :         AgentVgwConfig  gw_cfg;
     601           0 :         VirtualGatewayConfig::SubnetList subnet_list = it->subnets();
     602           0 :         VirtualGatewayConfig::SubnetList route_list = it->routes();
     603           0 :         vector<string> ip_blocks_list;
     604           0 :         vector<string> route_str_list;
     605             : 
     606           0 :         SubnetToStringList(subnet_list, ip_blocks_list);
     607           0 :         SubnetToStringList(route_list, route_str_list);
     608             : 
     609           0 :         gw_cfg.set_interface_name(it->interface_name());
     610           0 :         gw_cfg.set_vrf_name(it->vrf_name());
     611           0 :         gw_cfg.set_ip_blocks_list(ip_blocks_list);
     612           0 :         gw_cfg.set_route_list(route_str_list);
     613             : 
     614           0 :         gw_cfg_list.push_back(gw_cfg);
     615           0 :         ++it;
     616           0 :     }
     617           0 :     vrouter_agent.set_gateway_cfg_list(gw_cfg_list);
     618           0 :     vrouter_agent.set_headless_mode_cfg(true);
     619           0 :     vrouter_agent.set_collector_server_list_cfg(param->collector_server_list());
     620           0 :     vrouter_agent.set_bgpaas_enabled(
     621           0 :             agent_->oper_db()->bgp_as_a_service()->IsConfigured());
     622           0 :     vrouter_agent.set_port_mirror_enabled(MirrorTable::GetInstance()->IsConfigured());
     623           0 :     vrouter_agent.set_loopback_ip(param->loopback_ip().to_string());
     624           0 :     std::vector<string> gateway_list;
     625           0 :     for (std::vector<Ip4Address>::const_iterator iter = param->gateway_list().begin();
     626           0 :          iter != param->gateway_list().end(); ++iter) {
     627           0 :         gateway_list.push_back((*iter).to_string());
     628             :     }
     629           0 :     vrouter_agent.set_gateway_list(gateway_list);
     630           0 : }
     631             : 
     632             : 
     633           0 : bool VrouterUveEntryBase::SendVrouterMsg() {
     634           0 :     VrouterAgent vrouter_agent;
     635           0 :     bool changed = false, bgp_aas, port_mirror;
     636             :     static bool first = true;
     637           0 :     vrouter_agent.set_name(agent_->agent_name());
     638           0 :     Ip4Address rid = agent_->router_id();
     639           0 :     vector<string> ip_list;
     640           0 :     vector<string> dns_list;
     641             : 
     642           0 :     if (first) {
     643             :         //Physical interface list
     644           0 :         vnsConstants vnsVrouterType;
     645             :         //vhost attributes
     646           0 :         const Interface *vhost = agent_->vhost_interface();
     647           0 :         if (vhost) {
     648           0 :             AgentInterface vitf;
     649           0 :             vitf.set_name(vhost->name());
     650           0 :             vitf.set_mac_address(GetMacAddress(vhost->mac()));
     651           0 :             vrouter_agent.set_vhost_if(vitf);
     652           0 :         }
     653             : 
     654             :         //Configuration. Needs to be sent only once because whenever config
     655             :         //changes agent will be restarted
     656           0 :         BuildAgentConfig(vrouter_agent);
     657             : 
     658             :         //Set the Agent mode
     659           0 :         if (agent_->tor_agent_enabled()) {
     660           0 :             vrouter_agent.set_mode(vnsVrouterType.VrouterAgentTypeMap.at
     661           0 :                 (VrouterAgentType::VROUTER_AGENT_TOR));
     662           0 :         } else if (agent_->tsn_enabled()) {
     663           0 :             vrouter_agent.set_mode(vnsVrouterType.VrouterAgentTypeMap.at
     664           0 :                 (VrouterAgentType::VROUTER_AGENT_TSN));
     665             :         } else {
     666           0 :             vrouter_agent.set_mode(vnsVrouterType.VrouterAgentTypeMap.at
     667           0 :                 (VrouterAgentType::VROUTER_AGENT_EMBEDDED));
     668             :         }
     669             : 
     670           0 :         if (agent_->vrouter_on_nic_mode()) {
     671           0 :             vrouter_agent.set_platform(vnsVrouterType.
     672             :                                        VrouterAgentPlatformTypeMap.at
     673           0 :                                        (VrouterAgentPlatformType::
     674             :                                         VROUTER_AGENT_ON_NIC));
     675           0 :         } else if (agent_->vrouter_on_host_dpdk()) {
     676           0 :             vrouter_agent.set_platform(vnsVrouterType.
     677             :                                        VrouterAgentPlatformTypeMap.at
     678           0 :                                        (VrouterAgentPlatformType::
     679             :                                         VROUTER_AGENT_ON_HOST_DPDK));
     680           0 :         } else if (agent_->vrouter_on_host()) {
     681           0 :             vrouter_agent.set_platform(vnsVrouterType.
     682             :                                        VrouterAgentPlatformTypeMap.at
     683           0 :                                        (VrouterAgentPlatformType::
     684             :                                         VROUTER_AGENT_ON_HOST));
     685             :         }
     686             : 
     687           0 :         vrouter_agent.set_subcluster_name(agent_->subcluster_name());
     688           0 :         vrouter_agent.set_vr_high_watermark(agent_->vr_limit_high_watermark());
     689           0 :         vrouter_agent.set_vr_low_watermark(agent_->vr_limit_low_watermark());
     690           0 :         first = false;
     691           0 :         changed = true;
     692           0 :     }
     693             : 
     694           0 :     VrouterObjectLimits vr_limits = agent_->GetVrouterObjectLimits();
     695           0 :     VrouterObjectLimits prev_vr_limits = prev_vrouter_.get_vr_limits();
     696           0 :     if (vr_limits != prev_vr_limits) {
     697           0 :         vrouter_agent.set_vr_limits(vr_limits);
     698           0 :         prev_vrouter_.set_vr_limits(vr_limits);
     699           0 :         changed = true;
     700             :     }
     701             : 
     702           0 :     if (prev_vrouter_.get_build_info() != BuildInfo) {
     703           0 :         vrouter_agent.set_build_info(BuildInfo);
     704           0 :         prev_vrouter_.set_build_info(BuildInfo);
     705           0 :         changed = true;
     706             :     }
     707             : 
     708           0 :     bgp_aas = agent_->oper_db()->bgp_as_a_service()->IsConfigured();
     709           0 :     if (prev_vrouter_.get_bgpaas_enabled() != bgp_aas) {
     710           0 :         vrouter_agent.set_bgpaas_enabled(bgp_aas);
     711           0 :         prev_vrouter_.set_bgpaas_enabled(bgp_aas);
     712           0 :         changed = true;
     713             :     }
     714             : 
     715           0 :     port_mirror = MirrorTable::GetInstance()->IsConfigured();
     716           0 :     if (prev_vrouter_.get_port_mirror_enabled() != port_mirror) {
     717           0 :         vrouter_agent.set_port_mirror_enabled(port_mirror);
     718           0 :         prev_vrouter_.set_port_mirror_enabled(port_mirror);
     719           0 :         changed = true;
     720             :     }
     721             : 
     722           0 :     vector<AgentInterface> phy_if_list;
     723           0 :     PhysicalInterfaceSet::iterator it = phy_intf_set_.begin();
     724           0 :     while (it != phy_intf_set_.end()) {
     725           0 :         AgentInterface pitf;
     726           0 :         const Interface *intf = *it;
     727           0 :         const PhysicalInterface *port = static_cast
     728             :             <const PhysicalInterface *>(intf);
     729           0 :         pitf.set_name(intf->name());
     730           0 :         pitf.set_mac_address(GetMacAddress(port->mac()));
     731           0 :         phy_if_list.push_back(pitf);
     732           0 :         ++it;
     733           0 :     }
     734           0 :     if (prev_vrouter_.get_phy_if() != phy_if_list) {
     735           0 :         vrouter_agent.set_phy_if(phy_if_list);
     736           0 :         prev_vrouter_.set_phy_if(phy_if_list);
     737           0 :         changed = true;
     738             :     }
     739             : 
     740           0 :     std::vector<AgentXmppPeer> xmpp_list;
     741           0 :     for (int count = 0; count < MAX_XMPP_SERVERS; count++) {
     742           0 :         AgentXmppPeer peer;
     743           0 :         if (!agent_->controller_ifmap_xmpp_server(count).empty()) {
     744           0 :             peer.set_ip(agent_->controller_ifmap_xmpp_server(count));
     745           0 :             AgentXmppChannel *ch = agent_->controller_xmpp_channel(count);
     746           0 :             if (ch == NULL) {
     747           0 :                 continue;
     748             :             }
     749           0 :             XmppChannel *xc = ch->GetXmppChannel();
     750           0 :             if (xc == NULL) {
     751           0 :                 continue;
     752             :             }
     753           0 :             if (ch->bgp_peer_id() && xc->GetPeerState() == xmps::READY) {
     754           0 :                 peer.set_status(true);
     755             :             } else {
     756           0 :                 peer.set_status(false);
     757             :             }
     758           0 :             peer.set_setup_time(agent_->controller_xmpp_channel_setup_time(count));
     759           0 :             if (agent_->ifmap_active_xmpp_server_index() == count) {
     760           0 :                 peer.set_primary(true);
     761             :             } else {
     762           0 :                 peer.set_primary(false);
     763             :             }
     764           0 :             xmpp_list.push_back(peer);
     765             :         }
     766           0 :     }
     767             : 
     768           0 :     if (!prev_vrouter_.__isset.xmpp_peer_list ||
     769           0 :         prev_vrouter_.get_xmpp_peer_list() != xmpp_list) {
     770           0 :         vrouter_agent.set_xmpp_peer_list(xmpp_list);
     771           0 :         prev_vrouter_.set_xmpp_peer_list(xmpp_list);
     772           0 :         changed = true;
     773             :     }
     774             :     /* Self IP list should be populated only if router_id is  configured */
     775           0 :     if (agent_->router_id_configured()) {
     776           0 :         ip_list.push_back(rid.to_string());
     777           0 :         if (!prev_vrouter_.__isset.self_ip_list ||
     778           0 :                 prev_vrouter_.get_self_ip_list() != ip_list) {
     779             : 
     780           0 :             vrouter_agent.set_self_ip_list(ip_list);
     781           0 :             prev_vrouter_.set_self_ip_list(ip_list);
     782           0 :             changed = true;
     783             :         }
     784             :     }
     785             : 
     786           0 :     for (int idx = 0; idx < MAX_XMPP_SERVERS; idx++) {
     787           0 :         if (!agent_->dns_server(idx).empty()) {
     788           0 :             dns_list.push_back(agent_->dns_server(idx));
     789             :         }
     790             :     }
     791             : 
     792           0 :     if (!prev_vrouter_.__isset.dns_servers ||
     793           0 :         prev_vrouter_.get_dns_servers() != dns_list) {
     794           0 :         vrouter_agent.set_dns_servers(dns_list);
     795           0 :         prev_vrouter_.set_dns_servers(dns_list);
     796           0 :         changed = true;
     797             :     }
     798             : 
     799           0 :     std::vector<VrouterAgentResUsage> limit_exceeded_list;
     800           0 :     VrouterAgentResUsage usage;
     801           0 :     bool limit_exceeded = false;
     802           0 :     bool table_limit = false;
     803           0 :     VrLimitExceeded res_usage_map = agent_->get_vr_limits_exceeded_map();
     804           0 :     for(VrLimitExceeded::iterator res_map_it = res_usage_map.begin();
     805           0 :         res_map_it != res_usage_map.end(); ++res_map_it ) {
     806           0 :         if (res_map_it->second != "Normal") {
     807           0 :             usage.set_name(res_map_it->first);
     808           0 :             usage.set_status(res_map_it->second);
     809           0 :             limit_exceeded_list.push_back(usage);
     810           0 :             if (res_map_it->second == "TableLimit" && !table_limit) {
     811           0 :                 table_limit = true;
     812           0 :                 limit_exceeded = true;
     813           0 :             } else if (res_map_it->second == "Exceeded" && !limit_exceeded ) {
     814           0 :                 limit_exceeded = true;
     815           0 :                 table_limit = false;
     816             :             }
     817             :         }
     818             :     }
     819             : 
     820           0 :     if (!prev_vrouter_.__isset.vr_limit_exceeded_list ||
     821           0 :         prev_vrouter_.get_vr_limit_exceeded_list() != limit_exceeded_list) {
     822           0 :         vrouter_agent.set_vr_limit_exceeded_list(limit_exceeded_list);
     823           0 :         prev_vrouter_.set_vr_limit_exceeded_list(limit_exceeded_list);
     824           0 :         vrouter_agent.set_res_limit(limit_exceeded);
     825           0 :         vrouter_agent.set_res_table_limit(table_limit);
     826           0 :         changed = true;
     827             :     }
     828             : 
     829           0 :     if (agent_->is_l3mh()) {
     830           0 :         std::vector<L3mhPhysicalInterfaceStatus> vr_l3mh_intf_list;
     831           0 :         bool l3mh_phy_interface_down = false;
     832           0 :         PhysicalInterfaceSet::iterator it = phy_intf_set_.begin();
     833           0 :         while (it != phy_intf_set_.end()) {
     834           0 :             L3mhPhysicalInterfaceStatus l3mh_interface_status;
     835           0 :             const Interface *intf = *it;
     836           0 :             l3mh_interface_status.set_name(intf->name());
     837           0 :             l3mh_interface_status.set_active(intf->os_oper_state());
     838           0 :             vr_l3mh_intf_list.push_back(l3mh_interface_status);
     839           0 :             if (!intf->os_oper_state())
     840           0 :                 l3mh_phy_interface_down = true;
     841           0 :             ++it;
     842           0 :         }
     843             : 
     844           0 :         if (!prev_vrouter_.__isset.vr_l3mh_intf_list ||
     845           0 :             prev_vrouter_.get_vr_l3mh_intf_list() != vr_l3mh_intf_list) {
     846           0 :             vrouter_agent.set_vr_l3mh_intf_list(vr_l3mh_intf_list);
     847           0 :             prev_vrouter_.set_vr_l3mh_intf_list(vr_l3mh_intf_list);
     848           0 :             vrouter_agent.set_l3mh_phy_interface_down(l3mh_phy_interface_down);
     849           0 :             changed = true;
     850             :         }
     851             : 
     852           0 :     }
     853           0 :     if (changed) {
     854           0 :         DispatchVrouterMsg(vrouter_agent);
     855             :     }
     856             : 
     857           0 :     VrouterStatsAgent stats;
     858           0 :     stats.set_name(agent_->agent_name());
     859           0 :     cpu_stats_count_++;
     860             :     /* CPU stats needs to be sent every minute. We are using '% 2' below
     861             :      * because timer is fired every 30 secs. If the timer interval is changed
     862             :      * we need to fix the '%' value below accordingly */
     863           0 :     if ((cpu_stats_count_ % 2) == 0) {
     864             :         static bool cpu_first = true;
     865           0 :         CpuLoadInfo cpu_load_info;
     866           0 :         CpuLoadData::FillCpuInfo(cpu_load_info, true);
     867           0 :         if (prev_stats_.get_cpu_info() != cpu_load_info || cpu_first) {
     868           0 :             stats.set_cpu_info(cpu_load_info);
     869           0 :             prev_stats_.set_cpu_info(cpu_load_info);
     870           0 :             changed = true;
     871           0 :             cpu_first = false;
     872           0 :             DispatchVrouterStatsMsg(stats);
     873             :         }
     874             : 
     875             :         //Stats oracle interface for cpu and mem stats. Needs to be sent
     876             :         //always regardless of whether the stats have changed since last send
     877           0 :         BuildAndSendComputeCpuStateMsg(cpu_load_info);
     878           0 :         cpu_stats_count_ = 0;
     879           0 :     }
     880           0 :     return changed;
     881           0 : }
     882             : 
     883           1 : void VrouterUveEntryBase::SendVrouterProuterAssociation
     884             :     (const vector<string> &list) {
     885           2 :     VrouterAgent vrouter_agent;
     886           1 :     vrouter_agent.set_name(agent_->agent_name());
     887           1 :     if (agent_->tor_agent_enabled()) {
     888           0 :         vrouter_agent.set_tor_prouter_list(list);
     889           1 :     } else if (agent_->tsn_enabled()) {
     890           0 :         vrouter_agent.set_tsn_prouter_list(list);
     891             :     } else {
     892           1 :         vrouter_agent.set_embedded_prouter_list(list);
     893             :     }
     894           1 :     DispatchVrouterMsg(vrouter_agent);
     895           1 : }
     896             : 
     897           0 : string VrouterUveEntryBase::GetMacAddress(const MacAddress &mac) const {
     898           0 :     return mac.ToString();
     899             : }
     900             : 
     901           0 : void VrouterUveEntryBase::DispatchVrouterStatsMsg(const VrouterStatsAgent &uve) {
     902           0 :     VrouterStats::Send(uve);
     903           0 : }
     904             : 
     905           0 : void VrouterUveEntryBase::DispatchComputeCpuStateMsg(const ComputeCpuState &ccs) {
     906           0 :     ComputeCpuStateTrace::Send(ccs);
     907           0 : }
     908             : 
     909           0 : void VrouterUveEntryBase::BuildAndSendComputeCpuStateMsg(const CpuLoadInfo &info) {
     910           0 :     ComputeCpuState astate;
     911           0 :     VrouterCpuInfo ainfo;
     912           0 :     vector<VrouterCpuInfo> aciv;
     913             : 
     914           0 :     astate.set_name(agent_->agent_name());
     915           0 :     ainfo.set_cpu_share(info.get_cpu_share());
     916           0 :     ainfo.set_mem_virt(info.get_meminfo().get_virt());
     917           0 :     ainfo.set_mem_res(info.get_meminfo().get_res());
     918           0 :     const SysMemInfo &sys_mem_info(info.get_sys_mem_info());
     919           0 :     ainfo.set_used_sys_mem(sys_mem_info.get_used() -
     920           0 :         sys_mem_info.get_buffers() - sys_mem_info.get_cached());
     921           0 :     ainfo.set_one_min_cpuload(info.get_cpuload().get_one_min_avg());
     922           0 :     aciv.push_back(ainfo);
     923           0 :     astate.set_cpu_info(aciv);
     924           0 :     DispatchComputeCpuStateMsg(astate);
     925           0 : }

Generated by: LCOV version 1.14