LCOV - code coverage report
Current view: top level - vnsw/agent/uve - agent_uve_base.cc (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 112 223 50.2 %
Date: 2026-11-09 02:10:49 Functions: 10 16 62.5 %
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 <base/cpuinfo.h>
       7             : #include <db/db.h>
       8             : #include <cmn/agent_cmn.h>
       9             : #include <oper/interface_common.h>
      10             : #include <oper/interface.h>
      11             : 
      12             : #include "vr_genetlink.h"
      13             : #include "nl_util.h"
      14             : 
      15             : #include <uve/agent_uve_base.h>
      16             : #include <uve/vn_uve_table_base.h>
      17             : #include <uve/stats_interval_types.h>
      18             : #include <init/agent_param.h>
      19             : #include <oper/mirror_table.h>
      20             : #include <oper/global_vrouter.h>
      21             : #include <oper/tag.h>
      22             : #include <uve/vrouter_stats_collector.h>
      23             : #include <cmn/agent_stats.h>
      24             : 
      25             : using process::ConnectionInfo;
      26             : using process::ConnectionType;
      27             : using process::ProcessState;
      28             : using process::ConnectionStatus;
      29             : using process::ConnectionState;
      30             : using process::ConnectionStateManager;
      31             : using process::g_process_info_constants;
      32             : 
      33             : 
      34             : const uint32_t AgentUveBase::kUveCountPerTimer;
      35             : 
      36             : const uint32_t AgentUveBase::kDefaultInterval;
      37             : 
      38             : const uint32_t AgentUveBase::kIncrementalInterval;
      39             : 
      40             : const uint64_t AgentUveBase::kBandwidthInterval;
      41             : 
      42             : 
      43             : AgentUveBase *AgentUveBase::singleton_;
      44             : 
      45           2 : AgentUveBase::AgentUveBase(Agent *agent, uint64_t intvl,
      46           2 :                            uint32_t default_intvl, uint32_t incremental_intvl)
      47           2 :     : vn_uve_table_(NULL), vm_uve_table_(NULL), vrouter_uve_entry_(NULL),
      48           2 :       prouter_uve_table_(new ProuterUveTable(agent, default_intvl)),
      49           2 :       interface_uve_table_(NULL),
      50           2 :       default_interval_(default_intvl),
      51           2 :       incremental_interval_(incremental_intvl),
      52           2 :       agent_(agent), bandwidth_intvl_(intvl),
      53           2 :       vrouter_stats_collector_(new VrouterStatsCollector(
      54           2 :                                    *(agent->event_manager()->io_service()),
      55           4 :                                    this)) {
      56           2 :     singleton_ = this;
      57           2 : }
      58             : 
      59           2 : AgentUveBase::~AgentUveBase() {
      60           2 : }
      61             : 
      62           0 : void AgentUveBase::BuildTagNamesFromList(const TagList &tl, UveTagData *info)
      63             :     const {
      64           0 :     TagTable *table = agent_->tag_table();
      65           0 :     TagList::const_iterator it = tl.begin();
      66           0 :     while (it != tl.end()) {
      67           0 :         uint64_t type = ((uint64_t)*it >> TagEntry::kTagTypeBitShift);
      68           0 :         switch (type) {
      69           0 :         case TagTable::APPLICATION:
      70           0 :             info->application = table->TagName(*it);
      71           0 :             break;
      72           0 :         case TagTable::TIER:
      73           0 :             info->tier = table->TagName(*it);
      74           0 :             break;
      75           0 :         case TagTable::SITE:
      76           0 :             info->site = table->TagName(*it);
      77           0 :             break;
      78           0 :         case TagTable::DEPLOYMENT:
      79           0 :             info->deployment = table->TagName(*it);
      80           0 :             break;
      81           0 :         case TagTable::LABEL:
      82           0 :             if (info->fill_type == UveTagData::SET) {
      83           0 :                 info->label_set.insert(table->TagName(*it));
      84           0 :                 break;
      85           0 :             } else if (info->fill_type == UveTagData::VECTOR) {
      86           0 :                 info->label_vector.push_back(table->TagName(*it));
      87           0 :                 break;
      88             :             }
      89           0 :             if (!info->labels.empty()) {
      90           0 :                 info->labels += ";";
      91             :             }
      92           0 :             info->labels.append(table->TagName(*it));
      93           0 :             break;
      94           0 :         case TagTable::NEUTRON_FWAAS:
      95           0 :             info->application = table->TagName(*it);
      96           0 :             break;
      97           0 :         default:
      98           0 :             if (info->fill_type == UveTagData::SET) {
      99           0 :                 info->custom_tag_set.insert(table->TagName(*it));
     100           0 :                 break;
     101           0 :             } else if (info->fill_type == UveTagData::VECTOR) {
     102           0 :                 info->custom_tag_vector.push_back(table->TagName(*it));
     103           0 :                 break;
     104             :             }
     105           0 :             if (!info->custom_tags.empty()) {
     106           0 :                 info->custom_tags += ";";
     107             :             }
     108           0 :             info->custom_tags.append(table->TagName(*it));
     109           0 :             break;
     110             :         }
     111           0 :         ++it;
     112             :     }
     113           0 : }
     114             : 
     115             : /* Web-UI requires tag-id to returned as hex string. This should start with 0x
     116             :  * and have exactly 12 digits/characters. Zero should be used for filling leading
     117             :  * characters if the tag-id is not 12 digits wide. Web-UI uses this id to do
     118             :  * lookup in API server */
     119           0 : string AgentUveBase::TagIDToHexString(uint64_t value) const {
     120           0 :     std::stringstream ss;
     121             :     ss << "0x" << std::setfill('0') <<
     122           0 :         std::setw(12) << std::hex << (uint64_t)value;
     123           0 :     return ss.str();
     124           0 : }
     125             : 
     126           0 : void AgentUveBase::BuildTagIdsFromList(const TagList &tl, UveTagData *info)
     127             :     const {
     128           0 :     TagList::const_iterator it = tl.begin();
     129           0 :     while (it != tl.end()) {
     130           0 :         uint64_t type = ((uint64_t)*it >> TagEntry::kTagTypeBitShift);
     131           0 :         switch (type) {
     132           0 :         case TagTable::APPLICATION:
     133           0 :             info->application = TagIDToHexString(*it);
     134           0 :             break;
     135           0 :         case TagTable::TIER:
     136           0 :             info->tier = TagIDToHexString(*it);
     137           0 :             break;
     138           0 :         case TagTable::SITE:
     139           0 :             info->site = TagIDToHexString(*it);
     140           0 :             break;
     141           0 :         case TagTable::DEPLOYMENT:
     142           0 :             info->deployment = TagIDToHexString(*it);
     143           0 :             break;
     144           0 :         case TagTable::LABEL:
     145           0 :             if (info->fill_type == UveTagData::SET) {
     146           0 :                 info->label_set.insert(TagIDToHexString(*it));
     147           0 :                 break;
     148           0 :             } else if (info->fill_type == UveTagData::VECTOR) {
     149           0 :                 info->label_vector.push_back(TagIDToHexString(*it));
     150           0 :                 break;
     151             :             }
     152           0 :             if (!info->labels.empty()) {
     153           0 :                 info->labels += ";";
     154             :             }
     155           0 :             info->labels.append(TagIDToHexString(*it));
     156           0 :             break;
     157           0 :         case TagTable::NEUTRON_FWAAS:
     158           0 :             info->application = TagIDToHexString(*it);
     159           0 :             break;
     160           0 :         default:
     161           0 :             if (info->fill_type == UveTagData::SET) {
     162           0 :                 info->custom_tag_set.insert(TagIDToHexString(*it));
     163           0 :                 break;
     164           0 :             } else if (info->fill_type == UveTagData::VECTOR) {
     165           0 :                 info->custom_tag_vector.push_back(TagIDToHexString(*it));
     166           0 :                 break;
     167             :             }
     168           0 :             if (!info->custom_tags.empty()) {
     169           0 :                 info->custom_tags += ";";
     170             :             }
     171           0 :             info->custom_tags.append(TagIDToHexString(*it));
     172           0 :             break;
     173             :         }
     174           0 :         ++it;
     175             :     }
     176           0 : }
     177             : 
     178           0 : void AgentUveBase::set_default_interval(uint32_t new_interval) {
     179           0 :     if (new_interval == 0) {
     180           0 :         default_interval_ = kDefaultInterval;
     181             :     } else {
     182           0 :         default_interval_ = new_interval;
     183             :     }
     184           0 : }
     185             : 
     186           0 : void AgentUveBase::set_incremental_interval(uint32_t new_interval) {
     187           0 :     if (new_interval == 0) {
     188           0 :         incremental_interval_ = kIncrementalInterval;
     189             :     } else {
     190           0 :         incremental_interval_ = new_interval;
     191             :     }
     192           0 : }
     193             : 
     194           2 : void AgentUveBase::Shutdown() {
     195           2 :     vn_uve_table_.get()->Shutdown();
     196           2 :     vm_uve_table_.get()->Shutdown();
     197           2 :     vrouter_uve_entry_.get()->Shutdown();
     198           2 :     prouter_uve_table_.get()->Shutdown();
     199           2 :     interface_uve_table_.get()->Shutdown();
     200           2 :     connection_state_manager_->Shutdown();
     201           2 :     vrouter_stats_collector_->Shutdown();
     202           2 : }
     203             : 
     204           2 : void AgentUveBase::Init() {
     205           2 :     std::string module_id(agent_->module_name());
     206           2 :     std::string instance_id(agent_->instance_id());
     207           2 :     EventManager *evm = agent_->event_manager();
     208           2 :     boost::asio::io_context &io = *evm->io_service();
     209             : 
     210           2 :     CpuLoadData::Init();
     211           2 :     connection_state_manager_ =
     212             :         ConnectionStateManager::
     213           2 :             GetInstance();
     214           2 :     agent_->set_connection_state(ConnectionState::GetInstance());
     215           2 :     connection_state_manager_->Init(io, agent_->agent_name(),
     216             :             module_id, instance_id,
     217             :             boost::bind(&AgentUveBase::VrouterAgentProcessState,
     218             :                         this, _1, _2, _3), "ObjectVRouter");
     219           2 : }
     220             : 
     221          62 : uint8_t AgentUveBase::ExpectedConnections(uint8_t &num_control_nodes,
     222             :                                           uint8_t &num_dns_servers) {
     223          62 :     uint8_t count = 0;
     224          62 :     AgentParam *cfg = agent_->params();
     225             : 
     226         186 :     for (int i = 0; i < MAX_XMPP_SERVERS; i++) {
     227         124 :         if (!agent_->controller_ifmap_xmpp_server(i).empty()) {
     228         103 :             num_control_nodes++;
     229         103 :             count++;
     230             :         }
     231         124 :         if (agent_->services() && !agent_->dns_server(i).empty()) {
     232          62 :             num_dns_servers++;
     233          62 :             count++;
     234             :         }
     235             :     }
     236             :     //Increment 1 for collector service
     237          62 :     if (cfg->collector_server_list().size() != 0) {
     238          62 :         count++;
     239             :     }
     240             : 
     241          62 :     return count;
     242             : }
     243             : 
     244         199 : void AgentUveBase::UpdateMessage(const ConnectionInfo &cinfo,
     245             :                              std::string &message) {
     246         199 :     if (message.empty()) {
     247          62 :         message = cinfo.get_type();
     248             :     } else {
     249         137 :         message += ", " + cinfo.get_type();
     250             :     }
     251         199 :     const std::string &name(cinfo.get_name());
     252         199 :     if (!name.empty()) {
     253         137 :         message += ":" + name;
     254             :     }
     255         199 : }
     256             : 
     257          62 : bool AgentUveBase::HasSelfConfiguration() const {
     258          62 :     if (!agent_ || !agent_->oper_db() || !agent_->oper_db()->global_vrouter()) {
     259           0 :         return false;
     260             :     }
     261          62 :     return agent_->oper_db()->global_vrouter()->configured();
     262             : }
     263             : 
     264          62 : void AgentUveBase::VrouterAgentProcessState
     265             :     (const std::vector<ConnectionInfo> &cinfos,
     266             :      ProcessState::type &pstate, std::string &message) {
     267          62 :     size_t num_conns = 0;
     268          62 :     uint8_t num_control_nodes = 0, num_dns_servers = 0;
     269          62 :     uint8_t down_control_nodes = 0;
     270          62 :     uint8_t expected_conns = ExpectedConnections(num_control_nodes,
     271          62 :                                                  num_dns_servers);
     272             :     std::string cup(g_process_info_constants.ConnectionStatusNames.
     273          62 :         find(ConnectionStatus::UP)->second);
     274          62 :     bool is_cup = true;
     275          62 :     bool is_tor_connected = false;
     276             :     string tor_type(g_process_info_constants.ConnectionTypeNames.
     277          62 :             find(ConnectionType::TOR)->second);
     278             :     // Iterate to determine process connectivity status
     279          62 :     for (std::vector<ConnectionInfo>::const_iterator it = cinfos.begin();
     280         285 :          it != cinfos.end(); it++) {
     281         223 :         const ConnectionInfo &cinfo(*it);
     282         223 :         const std::string &conn_status(cinfo.get_status());
     283         223 :         if (cinfo.get_type() == tor_type) {
     284           0 :             is_tor_connected = true;
     285           0 :             continue;
     286             :         }
     287             :         /* Don't consider ConnectionType::TOR type for counting connections.
     288             :          * contrail-tor-agent is not supposed to report as Non-Functional when
     289             :          * it is in backup mode, but contrail-tor-agent does not have a way to
     290             :          * figure out that it is in backup mode. Hence for contrail-tor-agent
     291             :          * (both active and backup modes) we don't consider connection to TOR
     292             :          * for reporting Node Status */
     293         223 :         num_conns++;
     294         223 :         if (conn_status != cup) {
     295         398 :             if (cinfo.get_name().compare(0, 13,
     296         398 :                 agent_->xmpp_control_node_prefix()) == 0) {
     297          83 :                 down_control_nodes++;
     298             :             }
     299         199 :             is_cup = false;
     300         199 :             UpdateMessage(cinfo, message);
     301             :         }
     302             :     }
     303          62 :     if ((num_control_nodes == 0) || (num_control_nodes == down_control_nodes)) {
     304          28 :         pstate = ProcessState::NON_FUNCTIONAL;
     305          28 :         if ((num_control_nodes == 0) && message.empty()) {
     306           0 :             message = "No control-nodes configured";
     307             :         }
     308          34 :     } else if (!is_tor_connected && agent_->tor_agent_enabled()) {
     309             :         // waiting for first TOR config to arrive
     310           0 :         pstate = ProcessState::NON_FUNCTIONAL;
     311           0 :         message += " No ToR Config";
     312             :     } else {
     313          34 :         pstate = ProcessState::FUNCTIONAL;
     314             :     }
     315          62 :     if (!is_cup) {
     316          62 :         message += " connection down";
     317             :     }
     318          62 :     if (!HasSelfConfiguration()) {
     319             :         // waiting for Global vrouter config
     320          60 :         pstate = ProcessState::NON_FUNCTIONAL;
     321          60 :         if (message.empty()) {
     322           0 :             message = "No Configuration for self";
     323             :         } else {
     324          60 :             message += ", No Configuration for self";
     325             :         }
     326             :     }
     327         146 :     for (int i = 0; i < MAX_XMPP_SERVERS; i++) {
     328         124 :         if (!agent_->controller_ifmap_xmpp_server(i).empty()) {
     329         103 :             if (agent_->stats()->xmpp_reconnects(i) >= 1) {
     330          40 :                 break;
     331             :             }
     332             :         }
     333             :     }
     334             : 
     335          62 :     if (num_conns != expected_conns) {
     336          24 :         message += " Number of connections:" + integerToString(num_conns) +
     337          36 :             ", Expected: " + integerToString(expected_conns);
     338          12 :         return;
     339             :     }
     340          50 :     return;
     341          62 : }
     342             : 
     343           2 : void AgentUveBase::RegisterDBClients() {
     344           2 :     vn_uve_table_.get()->RegisterDBClients();
     345           2 :     vm_uve_table_.get()->RegisterDBClients();
     346           2 :     vrouter_uve_entry_.get()->RegisterDBClients();
     347           2 :     prouter_uve_table_.get()->RegisterDBClients();
     348           2 :     interface_uve_table_.get()->RegisterDBClients();
     349           2 : }
     350             : 
     351           2 : void AgentUveBase::InitDone() {
     352           2 :     vrouter_stats_collector_->InitDone();
     353           2 : }

Generated by: LCOV version 1.14