LCOV - code coverage report
Current view: top level - ifmap - ifmap_xmpp.cc (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 111 323 34.4 %
Date: 2026-06-22 02:21:21 Functions: 20 41 48.8 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
       3             :  */
       4             : 
       5             : #include <sandesh/request_pipeline.h>
       6             : 
       7             : #include "ifmap/ifmap_xmpp.h"
       8             : #include <boost/foreach.hpp>
       9             : #include <boost/assign/list_of.hpp>
      10             : 
      11             : #include "base/util.h"
      12             : #include "base/logging.h"
      13             : 
      14             : #include "ifmap/ifmap_factory.h"
      15             : #include "ifmap/ifmap_log.h"
      16             : #include "ifmap/ifmap_sandesh_context.h"
      17             : #include "ifmap/ifmap_server_show_types.h"
      18             : #include "ifmap/ifmap_log_types.h"
      19             : #include "ifmap/ifmap_update_sender.h"
      20             : 
      21             : #include "xmpp/xmpp_connection.h"
      22             : #include "xmpp/xmpp_server.h"
      23             : 
      24             : const std::string IFMapXmppChannel::NoFqnSet = "NoFqnSet";
      25             : 
      26             : // There are 3 task interactions:
      27             : // "xmpp::StateMachine" gives all the channel triggers.
      28             : // "db::IFMapTable" does all the work related to those triggers - except Ready
      29             : // "bgp::Config" does the final channel-unregister
      30             : //
      31             : // "xmpp::StateMachine" task gives us 5 triggers:
      32             : // 1. Ready/NotReady indicating the channel create/delete
      33             : // 2. VR-subscribe indicating the existence of the agent
      34             : // 3. VM-sub/unsub indicating the create/delete of a virtual-machine
      35             : // Process all the triggers in the context of the db::IFMapTable task - except
      36             : // the 'ready' trigger that is processed right away.
      37             : // #1 must be processed via the IFMapChannelManager.
      38             : // #2/#3 must be processed via the IFMapXmppChannel since they are
      39             : // channel-specific
      40             : //
      41             : // "bgp::Config":
      42             : // The NotReady trigger will cleanup the channel related resources and then
      43             : // Unregister via ProcessChannelUnregister() in the context of bgp::Config.
      44             : class ChannelEventProcTask : public Task {
      45             : public:
      46             :     // To be used for #1
      47           7 :     explicit ChannelEventProcTask(const ChannelEventInfo &ev,
      48             :                                   IFMapChannelManager *mgr)
      49           7 :         : Task(TaskScheduler::GetInstance()->GetTaskId("db::IFMapTable"), 0),
      50           7 :           event_info_(ev), ifmap_channel_manager_(mgr) {
      51           7 :     }
      52             : 
      53             :     // To be used for #2/#3
      54           0 :     explicit ChannelEventProcTask(const ChannelEventInfo &ev,
      55             :                                   IFMapXmppChannel *chnl)
      56           0 :         : Task(TaskScheduler::GetInstance()->GetTaskId("db::IFMapTable"), 0),
      57           0 :           event_info_(ev), ifmap_chnl_(chnl) {
      58           0 :     }
      59             : 
      60           7 :     virtual bool Run() {
      61           7 :         if (event_info_.event == XCE_NOT_READY) {
      62           7 :             ifmap_channel_manager_->ProcessChannelNotReady(event_info_.channel);
      63           0 :         } else if (event_info_.event == XCE_VR_SUBSCRIBE) {
      64           0 :             ifmap_chnl_->ProcessVrSubscribe(event_info_.name);
      65           0 :         } else if (event_info_.event == XCE_VM_SUBSCRIBE) {
      66           0 :             ifmap_chnl_->ProcessVmSubscribe(event_info_.name);
      67           0 :         } else if (event_info_.event == XCE_VM_UNSUBSCRIBE) {
      68           0 :             ifmap_chnl_->ProcessVmUnsubscribe(event_info_.name);
      69             :         }
      70             : 
      71           7 :         return true;
      72             :     }
      73           0 :     std::string Description() const { return "ChannelEventProcTask"; }
      74             : 
      75             : private:
      76             :     ChannelEventInfo event_info_;
      77             :     IFMapChannelManager *ifmap_channel_manager_;
      78             :     IFMapXmppChannel *ifmap_chnl_;
      79             : };
      80             : 
      81             : class IFMapXmppChannel::IFMapSender : public IFMapClient {
      82             : public:
      83             :     IFMapSender(IFMapXmppChannel *parent);
      84             : 
      85             :     virtual bool SendUpdate(const std::string &msg);
      86             : 
      87           0 :     virtual std::string ToString() const { return identifier_; }
      88           7 :     virtual const std::string &identifier() const { return identifier_; }
      89             :     const std::string &hostname() const { return hostname_; }
      90             :     IFMapXmppChannel *parent() { return parent_; }
      91             : 
      92           0 :     void SetIdentifier(const std::string &identifier) {
      93           0 :         identifier_ = identifier;
      94           0 :     }
      95             : 
      96             : private:
      97             :     IFMapXmppChannel *parent_;
      98             :     std::string hostname_;      // hostname
      99             :     std::string identifier_;    // FQN
     100             : };
     101             : 
     102           7 : IFMapXmppChannel::IFMapSender::IFMapSender(IFMapXmppChannel *parent)
     103           7 :     : parent_(parent), hostname_(parent_->channel_->ToString()) {
     104           7 : }
     105             : 
     106           0 : bool IFMapXmppChannel::IFMapSender::SendUpdate(const std::string &msg) {
     107           0 :     bool sent = parent_->channel_->Send(
     108           0 :         reinterpret_cast<const uint8_t *>(msg.data()), msg.size(), &msg,
     109             :         xmps::CONFIG,
     110             :         boost::bind(&IFMapXmppChannel::WriteReadyCb, parent_, _1));
     111             : 
     112           0 :     if (sent) {
     113           0 :         incr_msgs_sent();
     114           0 :         incr_bytes_sent(msg.size());
     115             :     } else {
     116           0 :         set_send_is_blocked(true);
     117           0 :         incr_msgs_blocked();
     118             :     }
     119           0 :     return sent;
     120             : }
     121             : 
     122           0 : void IFMapXmppChannel::WriteReadyCb(const boost::system::error_code &ec) {
     123           0 :     ifmap_client_->set_send_is_blocked(false);
     124           0 :     ifmap_server_->sender()->SendActive(ifmap_client_->index());
     125           0 : }
     126             : 
     127           7 : IFMapXmppChannel::IFMapXmppChannel(XmppChannel *channel, IFMapServer *server,
     128           7 :         IFMapChannelManager *ifmap_channel_manager)
     129           7 :     : peer_id_(xmps::CONFIG), channel_(channel), ifmap_server_(server),
     130           7 :       ifmap_channel_manager_(ifmap_channel_manager),
     131           7 :       ifmap_client_(new IFMapSender(this)), client_added_(false),
     132          14 :       channel_name_(channel->connection()->ToUVEKey()) {
     133             : 
     134           7 :     ifmap_client_->SetName(channel->connection()->ToUVEKey());
     135           7 :     channel_->RegisterReceive(xmps::CONFIG,
     136             :                               boost::bind(&IFMapXmppChannel::ReceiveUpdate,
     137             :                                           this, _1));
     138           7 : }
     139             : 
     140           7 : IFMapXmppChannel::~IFMapXmppChannel() {
     141           7 :     delete ifmap_client_;
     142             :     // Enqueue Unregister and process in the context of bgp::Config task
     143           7 :     channel_->UnRegisterWriteReady(xmps::CONFIG);
     144           7 :     ifmap_channel_manager_->EnqueueChannelUnregister(channel_);
     145           7 : }
     146             : 
     147             : // iqn should be [virtual-router:FQN-of-vr]
     148           0 : std::string IFMapXmppChannel::VrSubscribeGetVrName(const std::string &iqn,
     149             :                                                    bool *valid_message) {
     150           0 :     std::string vr_name;
     151           0 :     size_t tstart = iqn.find("virtual-router:");
     152           0 :     if (tstart == 0) {
     153           0 :         vr_name = std::string(iqn, (sizeof("virtual-router:") - 1));
     154           0 :         *valid_message = true;
     155             :     } else {
     156           0 :         *valid_message = false;
     157             :     }
     158             : 
     159           0 :     return vr_name;
     160           0 : }
     161             : 
     162             : // iqn should be [virtual-machine:UUID-of-vm]
     163           0 : std::string IFMapXmppChannel::VmSubscribeGetVmUuid(const std::string &iqn,
     164             :                                                    bool *valid_message) {
     165           0 :     std::string vm_uuid;
     166           0 :     size_t tstart = iqn.find("virtual-machine:");
     167           0 :     if (tstart == 0) {
     168           0 :         vm_uuid = std::string(iqn, (sizeof("virtual-machine:") - 1));
     169           0 :         *valid_message = true;
     170             :     } else {
     171           0 :         ifmap_channel_manager_->incr_invalid_vm_subscribe_messages();
     172           0 :         *valid_message = false;
     173             :     }
     174             : 
     175           0 :     return vm_uuid;
     176           0 : }
     177             : 
     178             : // If add-client was sent to ifmap_server, we must send delete-client too and
     179             : // vice-versa
     180           7 : bool IFMapXmppChannel::MustProcessChannelNotReady() {
     181           7 :     return client_added_;
     182             : }
     183             : 
     184           7 : const std::string& IFMapXmppChannel::FQName() const {
     185           7 :     if (ifmap_client_) {
     186           7 :         return ifmap_client_->identifier();
     187             :     } else {
     188           0 :         return IFMapXmppChannel::NoFqnSet;
     189             :     }
     190             : }
     191             : 
     192           0 : void IFMapXmppChannel::ProcessVrSubscribe(const std::string &identifier) {
     193             :     // If we have already received a vr-subscribe on this channel...
     194           0 :     if (client_added_) {
     195           0 :         ifmap_channel_manager_->incr_duplicate_vrsub_messages();
     196           0 :         IFMAP_XMPP_WARN(IFMapDuplicateVrSub, channel_name(), FQName());
     197           0 :         return;
     198             :     }
     199             : 
     200           0 :     ifmap_client_->SetIdentifier(identifier);
     201           0 :     bool add_client = true;
     202           0 :     ifmap_server_->ProcessClientWork(add_client, ifmap_client_);
     203           0 :     client_added_ = true;
     204           0 :     IFMAP_XMPP_DEBUG(IFMapXmppVrSubUnsub, "VrSubscribe", channel_name(),
     205             :                      FQName());
     206             : }
     207             : 
     208           0 : void IFMapXmppChannel::ProcessVmSubscribe(const std::string &vm_uuid) {
     209           0 :     if (!client_added_) {
     210             :         // If we didnt receive the vr-subscribe for this vm...
     211           0 :         ifmap_channel_manager_->incr_vmsub_novrsub_messages();
     212           0 :         IFMAP_XMPP_WARN(IFMapNoVrSub, "VmSubscribe", channel_name(), FQName(),
     213             :                         vm_uuid);
     214           0 :         return;
     215             :     }
     216             : 
     217           0 :     if (!ifmap_client_->HasAddedVm(vm_uuid)) {
     218           0 :         ifmap_client_->AddVm(vm_uuid);
     219           0 :         bool subscribe = true;
     220           0 :         ifmap_server_->ProcessVmSubscribe(ifmap_client_->identifier(), vm_uuid,
     221           0 :                                           subscribe, ifmap_client_->HasVms());
     222           0 :         IFMAP_XMPP_DEBUG(IFMapXmppVmSubUnsub, "VmSubscribe", channel_name(),
     223             :                          FQName(), vm_uuid);
     224             :     } else {
     225             :         // If we have already received a subscribe for this vm
     226           0 :         ifmap_channel_manager_->incr_duplicate_vmsub_messages();
     227           0 :         IFMAP_XMPP_WARN(IFMapDuplicateVmSub, channel_name(), FQName(), vm_uuid);
     228             :     }
     229             : }
     230             : 
     231           0 : void IFMapXmppChannel::ProcessVmUnsubscribe(const std::string &vm_uuid) {
     232             :     // If we didnt receive the vr-sub for this vm, ignore the request
     233           0 :     if (!client_added_) {
     234           0 :         ifmap_channel_manager_->incr_vmunsub_novrsub_messages();
     235           0 :         IFMAP_XMPP_WARN(IFMapNoVrSub, "VmUnsubscribe", channel_name(), FQName(),
     236             :                         vm_uuid);
     237           0 :         return;
     238             :     }
     239             : 
     240           0 :     if (ifmap_client_->HasAddedVm(vm_uuid)) {
     241           0 :         ifmap_client_->DeleteVm(vm_uuid);
     242           0 :         bool subscribe = false;
     243           0 :         ifmap_server_->ProcessVmSubscribe(ifmap_client_->identifier(), vm_uuid,
     244           0 :                                           subscribe, ifmap_client_->HasVms());
     245           0 :         IFMAP_XMPP_DEBUG(IFMapXmppVmSubUnsub, "VmUnsubscribe", channel_name(),
     246             :                          FQName(), vm_uuid);
     247             :     } else {
     248             :         // If we didnt receive the subscribe for this vm, ignore the unsubscribe
     249           0 :         ifmap_channel_manager_->incr_vmunsub_novmsub_messages();
     250           0 :         IFMAP_XMPP_WARN(IFMapNoVmSub, channel_name(), FQName(), vm_uuid);
     251             :     }
     252             : }
     253             : 
     254           0 : void IFMapXmppChannel::EnqueueVrSubscribe(const std::string &identifier) {
     255           0 :     ChannelEventInfo info;
     256           0 :     info.event = XCE_VR_SUBSCRIBE;
     257           0 :     info.name = identifier;
     258             : 
     259           0 :     ChannelEventProcTask *proc_task = new ChannelEventProcTask(info, this);
     260           0 :     TaskScheduler *scheduler = TaskScheduler::GetInstance();
     261           0 :     scheduler->Enqueue(proc_task);
     262           0 : }
     263             : 
     264           0 : void IFMapXmppChannel::EnqueueVmSubUnsub(bool subscribe,
     265             :                                          const std::string &vm_uuid) {
     266           0 :     ChannelEventInfo info;
     267           0 :     info.event = (subscribe == true) ? XCE_VM_SUBSCRIBE : XCE_VM_UNSUBSCRIBE;
     268           0 :     info.name = vm_uuid;
     269             : 
     270           0 :     ChannelEventProcTask *proc_task = new ChannelEventProcTask(info, this);
     271           0 :     TaskScheduler *scheduler = TaskScheduler::GetInstance();
     272           0 :     scheduler->Enqueue(proc_task);
     273           0 : }
     274             : 
     275             : // This runs in the context of the "xmpp::StateMachine" and queues all requests
     276             : // which are then processed in the context of "db::IFMapTable"
     277           0 : void IFMapXmppChannel::ReceiveUpdate(const XmppStanza::XmppMessage *msg) {
     278             : 
     279           0 :     if (msg->type == XmppStanza::IQ_STANZA) {
     280           0 :         const XmppStanza::XmppMessageIq *iq =
     281             :             static_cast<const XmppStanza::XmppMessageIq *>(msg);
     282             : 
     283           0 :         const char* const vr_string = "virtual-router:";
     284           0 :         const char* const vm_string = "virtual-machine:";
     285           0 :         if ((iq->iq_type.compare("set") == 0) &&
     286           0 :             (iq->action.compare("subscribe") == 0)) {
     287           0 :             if (iq->node.compare(0, strlen(vr_string), vr_string) == 0) {
     288           0 :                 bool valid_message = false;
     289           0 :                 std::string vr_name = VrSubscribeGetVrName(iq->node,
     290           0 :                                                            &valid_message);
     291           0 :                 if (valid_message) {
     292           0 :                     EnqueueVrSubscribe(vr_name);
     293             :                 }
     294           0 :             } else if (iq->node.compare(0, strlen(vm_string), vm_string) == 0) {
     295           0 :                 bool valid_message = false;
     296           0 :                 std::string vm_uuid = VmSubscribeGetVmUuid(iq->node,
     297           0 :                                                            &valid_message);
     298           0 :                 if (valid_message) {
     299           0 :                     bool subscribe = true;
     300           0 :                     EnqueueVmSubUnsub(subscribe, vm_uuid);
     301             :                 }
     302           0 :             } else {
     303           0 :                 ifmap_channel_manager_->incr_unknown_subscribe_messages();
     304           0 :                 IFMAP_XMPP_WARN(IFMapXmppUnknownMessage, iq->iq_type,
     305             :                                 iq->action, iq->node, channel_name());
     306             :             }
     307             :         }
     308           0 :         if ((iq->iq_type.compare("set") == 0) &&
     309           0 :             (iq->action.compare("unsubscribe") == 0)) {
     310           0 :             if (iq->node.compare(0, strlen(vm_string), vm_string) == 0) {
     311           0 :                 bool valid_message = false;
     312           0 :                 std::string vm_uuid = VmSubscribeGetVmUuid(iq->node,
     313           0 :                                                            &valid_message);
     314           0 :                 if (valid_message) {
     315           0 :                     bool subscribe = false;
     316           0 :                     EnqueueVmSubUnsub(subscribe, vm_uuid);
     317             :                 }
     318           0 :             } else {
     319           0 :                 ifmap_channel_manager_->incr_unknown_unsubscribe_messages();
     320           0 :                 IFMAP_XMPP_WARN(IFMapXmppUnknownMessage, iq->iq_type,
     321             :                                 iq->action, iq->node, channel_name());
     322             :             }
     323             :         }
     324             :     }
     325           0 : }
     326             : 
     327           0 : IFMapClient *IFMapXmppChannel::Sender() {
     328           0 :     return ifmap_client_;
     329             : }
     330             : 
     331           0 : uint64_t IFMapXmppChannel::msgs_sent() const {
     332           0 :     return ifmap_client_->msgs_sent();
     333             : }
     334             : 
     335             : // IFMapClient Manager routines
     336           5 : IFMapChannelManager::IFMapChannelManager(XmppServer *xmpp_server,
     337           5 :                                          IFMapServer *ifmap_server)
     338           5 :     : xmpp_server_(xmpp_server), ifmap_server_(ifmap_server),
     339           5 :       config_task_work_queue_(
     340             :           TaskScheduler::GetInstance()->GetTaskId("bgp::Config"),
     341             :           0, boost::bind(&IFMapChannelManager::ProcessChannelUnregister,
     342           5 :                          this, _1)) {
     343           5 :     unknown_subscribe_messages = 0;
     344           5 :     unknown_unsubscribe_messages = 0;
     345           5 :     duplicate_channel_ready_messages = 0;
     346           5 :     invalid_channel_not_ready_messages = 0;
     347           5 :     invalid_channel_state_messages = 0;
     348           5 :     invalid_vm_subscribe_messages = 0;
     349           5 :     vmsub_novrsub_messages = 0;
     350           5 :     vmunsub_novrsub_messages = 0;
     351           5 :     vmunsub_novmsub_messages = 0;
     352           5 :     duplicate_vrsub_messages = 0;
     353           5 :     duplicate_vmsub_messages = 0;
     354           5 :     xmpp_server_->RegisterConnectionEvent(xmps::CONFIG,
     355             :         boost::bind(&IFMapChannelManager::IFMapXmppChannelEventCb, this, _1,
     356             :                     _2));
     357           5 : }
     358             : 
     359           8 : IFMapChannelManager::~IFMapChannelManager() {
     360           5 :     std::scoped_lock lock(channel_map_mutex_);
     361           5 :     STLDeleteElements(&channel_map_);
     362           8 : }
     363             : 
     364          14 : IFMapXmppChannel *IFMapChannelManager::FindChannel(XmppChannel *channel) {
     365          14 :     std::scoped_lock lock(channel_map_mutex_);
     366             :     ChannelMap::iterator loc =
     367          14 :         channel_map_.find(const_cast<XmppChannel *>(channel));
     368          14 :     if (loc != channel_map_.end()) {
     369           7 :         return loc->second;
     370             :     }
     371           7 :     return NULL;
     372          14 : }
     373             : 
     374           0 : IFMapXmppChannel *IFMapChannelManager::FindChannel(std::string tostring) {
     375           0 :     std::scoped_lock lock(channel_map_mutex_);
     376           0 :     BOOST_FOREACH(ChannelMap::value_type &i, channel_map_) {
     377           0 :         if (i.second->ToString() == tostring)
     378           0 :             return i.second;
     379             :     }
     380           0 :     return NULL;
     381           0 : }
     382             : 
     383           7 : IFMapXmppChannel *IFMapChannelManager::CreateIFMapXmppChannel(
     384             :         XmppChannel *channel) {
     385             :     IFMapXmppChannel *ifmap_chnl = IfmapStaticObjectFactory::
     386           7 :         Create<IFMapXmppChannel>(channel,
     387             :             ifmap_server_,
     388           7 :             this);
     389           7 :     std::scoped_lock lock(channel_map_mutex_);
     390           7 :     channel_map_.insert(std::make_pair(channel, ifmap_chnl));
     391           7 :     return ifmap_chnl;
     392           7 : }
     393             : 
     394           7 : void IFMapChannelManager::DeleteIFMapXmppChannel(IFMapXmppChannel *ifmap_chnl) {
     395           7 :     std::scoped_lock lock(channel_map_mutex_);
     396           7 :     channel_map_.erase(ifmap_chnl->channel());
     397           7 :     delete ifmap_chnl;
     398           7 : }
     399             : 
     400           7 : void IFMapChannelManager::ProcessChannelReady(XmppChannel *channel) {
     401           7 :     IFMapXmppChannel *ifmap_chnl = FindChannel(channel);
     402           7 :     if (ifmap_chnl == NULL) {
     403           7 :         IFMAP_XMPP_DEBUG(IFMapXmppChannelEvent, "Create",
     404             :             channel->connection()->ToUVEKey(), IFMapXmppChannel::NoFqnSet);
     405           7 :         CreateIFMapXmppChannel(channel);
     406           7 :         ConfigClientManager *client_manager = ifmap_server_->get_config_manager();
     407           7 :         if (client_manager && !client_manager->GetEndOfRibComputed()) {
     408           0 :             IFMAP_XMPP_DEBUG(IFMapXmppChannelEvent, "Close",
     409             :                              channel->connection()->ToUVEKey(),
     410             :                              IFMapXmppChannel::NoFqnSet);
     411           0 :             channel->Close();
     412             :         }
     413             :     } else {
     414           0 :         incr_duplicate_channel_ready_messages();
     415             :     }
     416           7 : }
     417             : 
     418           7 : void IFMapChannelManager::ProcessChannelNotReady(XmppChannel *channel) {
     419           7 :     IFMapXmppChannel *ifmap_chnl = FindChannel(channel);
     420           7 :     if (ifmap_chnl) {
     421             :         // If we have received subscriptions and ifmap_server knows about the
     422             :         // client for this channel, ask ifmap_server to cleanup.
     423           7 :         std::string fq_name = ifmap_chnl->FQName();
     424           7 :         if (ifmap_chnl->MustProcessChannelNotReady()) {
     425           0 :             bool add_client = false;
     426           0 :             ifmap_server_->ProcessClientWork(add_client, ifmap_chnl->Sender());
     427             :         }
     428           7 :         IFMAP_XMPP_DEBUG(IFMapXmppChannelEvent, "Destroy",
     429             :                          channel->connection()->ToUVEKey(), fq_name);
     430           7 :         DeleteIFMapXmppChannel(ifmap_chnl);
     431           7 :     } else {
     432           0 :         incr_invalid_channel_not_ready_messages();
     433             :     }
     434           7 : }
     435             : 
     436           7 : void IFMapChannelManager::EnqueueChannelEvent(XCEvent event,
     437             :                                               XmppChannel *channel) {
     438           7 :     ChannelEventInfo info;
     439           7 :     info.event = event;
     440           7 :     info.channel = channel;
     441             : 
     442           7 :     ChannelEventProcTask *proc_task = new ChannelEventProcTask(info, this);
     443           7 :     TaskScheduler *scheduler = TaskScheduler::GetInstance();
     444           7 :     scheduler->Enqueue(proc_task);
     445           7 : }
     446             : 
     447             : // This runs in the context of the "xmpp::StateMachine"
     448          14 : void IFMapChannelManager::IFMapXmppChannelEventCb(XmppChannel *channel,
     449             :                                                   xmps::PeerState state) {
     450          14 :     if (state == xmps::READY) {
     451             :         // Process the READY right away
     452           7 :         ProcessChannelReady(channel);
     453           7 :     } else if (state == xmps::NOT_READY) {
     454             :         // Queue the NOT_READY to be processed via the "db::IFMapTable" task
     455           7 :         EnqueueChannelEvent(XCE_NOT_READY, channel);
     456             :     } else {
     457           0 :         incr_invalid_channel_state_messages();
     458             :     }
     459          14 : }
     460             : 
     461             : // This runs in the context of bgp::Config
     462           7 : bool IFMapChannelManager::ProcessChannelUnregister(ConfigTaskQueueEntry entry) {
     463           7 :     IFMAP_XMPP_DEBUG(IFMapChannelUnregisterMessage,
     464             :                      "Unregistering config peer for channel",
     465             :                      entry.channel->connection()->ToUVEKey());
     466           7 :     entry.channel->UnRegisterReceive(xmps::CONFIG);
     467           7 :     return true;
     468             : }
     469             : 
     470           7 : void IFMapChannelManager::EnqueueChannelUnregister(XmppChannel *channel) {
     471             :     // Let ProcessChannelUnregister() unregister in the context of bgp::Config
     472             :     ConfigTaskQueueEntry entry;
     473           7 :     entry.channel = channel;
     474           7 :     config_task_work_queue_.Enqueue(entry);
     475           7 : }
     476             : 
     477           0 : void IFMapChannelManager::FillChannelMap(
     478             :         std::vector<IFMapXmppChannelMapEntry> *out_map) {
     479           0 :     std::scoped_lock lock(channel_map_mutex_);
     480           0 :     for (ChannelMap::iterator iter = channel_map_.begin();
     481           0 :          iter != channel_map_.end(); ++iter) {
     482           0 :         IFMapXmppChannel *ifmap_chnl = iter->second;
     483           0 :         IFMapXmppChannelMapEntry entry;
     484           0 :         entry.set_client_name(ifmap_chnl->FQName());
     485           0 :         entry.set_host_name(ifmap_chnl->channel()->ToString());
     486           0 :         entry.set_channel_name(ifmap_chnl->channel_name());
     487           0 :         entry.set_client_added(ifmap_chnl->get_client_added());
     488           0 :         out_map->push_back(entry);
     489           0 :     }
     490           0 : }
     491             : 
     492           0 : static bool IFMapXmppShowReqHandleRequest(const Sandesh *sr,
     493             :                                           const RequestPipeline::PipeSpec ps,
     494             :                                           int stage, int instNum,
     495             :                                           RequestPipeline::InstData *data) {
     496             :     const IFMapXmppShowReq *request =
     497           0 :         static_cast<const IFMapXmppShowReq *>(ps.snhRequest_.get());
     498             :     IFMapSandeshContext *sctx =
     499           0 :         static_cast<IFMapSandeshContext *>(request->module_context("IFMap"));
     500             :     IFMapChannelManager *ifmap_channel_manager =
     501           0 :         sctx->ifmap_server()->get_ifmap_channel_manager();
     502             : 
     503           0 :     IFMapXmppShowResp *response = new IFMapXmppShowResp();
     504           0 :     response->set_context(request->context());
     505           0 :     response->set_more(false);
     506             : 
     507           0 :     if (!ifmap_channel_manager) {
     508           0 :         response->Response();
     509           0 :         return true;
     510             :     }
     511             : 
     512           0 :     IFMapChannelManagerInfo channel_manager_info;
     513           0 :     IFMapChannelManagerStats channel_manager_stats;
     514             : 
     515           0 :     channel_manager_stats.set_unknown_subscribe_messages(
     516             :         ifmap_channel_manager->get_unknown_subscribe_messages());
     517           0 :     channel_manager_stats.set_unknown_unsubscribe_messages(
     518             :         ifmap_channel_manager->get_unknown_unsubscribe_messages());
     519           0 :     channel_manager_stats.set_duplicate_channel_ready_messages(
     520             :         ifmap_channel_manager->get_duplicate_channel_ready_messages());
     521           0 :     channel_manager_stats.set_invalid_channel_not_ready_messages(
     522             :         ifmap_channel_manager->get_invalid_channel_not_ready_messages());
     523           0 :     channel_manager_stats.set_invalid_channel_state_messages(
     524             :         ifmap_channel_manager->get_invalid_channel_state_messages());
     525           0 :     channel_manager_stats.set_invalid_vm_subscribe_messages(
     526             :         ifmap_channel_manager->get_invalid_vm_subscribe_messages());
     527           0 :     channel_manager_stats.set_vmsub_novrsub_messages(
     528             :         ifmap_channel_manager->get_vmsub_novrsub_messages());
     529           0 :     channel_manager_stats.set_vmunsub_novrsub_messages(
     530             :         ifmap_channel_manager->get_vmunsub_novrsub_messages());
     531           0 :     channel_manager_stats.set_vmunsub_novmsub_messages(
     532             :         ifmap_channel_manager->get_vmunsub_novmsub_messages());
     533           0 :     channel_manager_stats.set_duplicate_vrsub_messages(
     534             :         ifmap_channel_manager->get_duplicate_vrsub_messages());
     535           0 :     channel_manager_stats.set_duplicate_vmsub_messages(
     536             :         ifmap_channel_manager->get_duplicate_vmsub_messages());
     537             : 
     538           0 :     IFMapXmppChannelMapList channel_map_list;
     539           0 :     std::vector<IFMapXmppChannelMapEntry> channel_map;
     540           0 :     ifmap_channel_manager->FillChannelMap(&channel_map);
     541           0 :     channel_map_list.set_channel_list(channel_map);
     542           0 :     channel_map_list.set_channel_count(channel_map.size());
     543             : 
     544           0 :     channel_manager_info.set_channel_manager_stats(channel_manager_stats);
     545           0 :     channel_manager_info.set_channel_manager_map(channel_map_list);
     546             : 
     547           0 :     response->set_channel_manager_info(channel_manager_info);
     548           0 :     response->Response();
     549             : 
     550             :     // Return 'true' so that we are not called again
     551           0 :     return true;
     552           0 : }
     553             : 
     554           0 : void IFMapXmppShowReq::HandleRequest() const {
     555             : 
     556           0 :     RequestPipeline::StageSpec s0;
     557           0 :     TaskScheduler *scheduler = TaskScheduler::GetInstance();
     558             : 
     559           0 :     s0.taskId_ = scheduler->GetTaskId("db::IFMapTable");
     560           0 :     s0.cbFn_ = IFMapXmppShowReqHandleRequest;
     561           0 :     s0.instances_.push_back(0);
     562             : 
     563           0 :     RequestPipeline::PipeSpec ps(this);
     564           0 :     ps.stages_= boost::assign::list_of(s0)
     565           0 :         .convert_to_container<std::vector<RequestPipeline::StageSpec> >();
     566           0 :     RequestPipeline rp(ps);
     567           0 : }
     568             : 

Generated by: LCOV version 1.14