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

Generated by: LCOV version 1.14