Line data Source code
1 : /* 2 : * Copyright (c) 2015 Juniper Networks, Inc. All rights reserved. 3 : */ 4 : #include "bgp/bgp_xmpp_sandesh.h" 5 : 6 : #include <string> 7 : #include <vector> 8 : 9 : #include "base/regex.h" 10 : #include "bgp/bgp_membership.h" 11 : #include "bgp/bgp_peer.h" 12 : #include "bgp/bgp_peer_internal_types.h" 13 : #include "bgp/bgp_sandesh.h" 14 : #include "bgp/bgp_server.h" 15 : #include "bgp/bgp_xmpp_channel.h" 16 : #include "xmpp/xmpp_connection.h" 17 : 18 : using contrail::regex; 19 : using contrail::regex_match; 20 : using contrail::regex_search; 21 : using std::string; 22 : using std::vector; 23 : 24 0 : static bool ShowXmppNeighborMatch(const BgpXmppChannel *bx_channel, 25 : const string &search_string, const regex &search_expr) { 26 0 : if (regex_search(bx_channel->ToString(), search_expr)) 27 0 : return true; 28 0 : string address_string = bx_channel->remote_endpoint().address().to_string(); 29 0 : if (regex_search(address_string, search_expr)) 30 0 : return true; 31 0 : if (search_string == "deleted" && bx_channel->peer_deleted()) 32 0 : return true; 33 0 : return false; 34 0 : } 35 : 36 0 : static void FillXmppNeighborInfo(BgpNeighborResp *bnr, 37 : const BgpSandeshContext *bsc, const BgpXmppChannel *bx_channel, 38 : bool summary) { 39 0 : bnr->set_peer(bx_channel->ToString()); 40 0 : bnr->set_peer_address(bx_channel->remote_endpoint().address().to_string()); 41 0 : bnr->set_transport_address(bx_channel->transport_address_string()); 42 0 : bnr->set_deleted(bx_channel->peer_deleted()); 43 0 : bnr->set_closed_at(UTCUsecToString(bx_channel->peer_closed_at())); 44 0 : bnr->set_local_address(bx_channel->local_endpoint().address().to_string()); 45 0 : bnr->set_peer_type("internal"); 46 0 : bnr->set_encoding("XMPP"); 47 0 : bnr->set_state(bx_channel->StateName()); 48 : 49 0 : const XmppConnection *connection = bx_channel->channel()->connection(); 50 0 : bnr->set_negotiated_hold_time(connection->GetNegotiatedHoldTime()); 51 0 : bnr->set_primary_path_count(bx_channel->Peer()->GetPrimaryPathCount()); 52 0 : bnr->set_task_instance(connection->GetTaskInstance()); 53 0 : bnr->set_auth_type(connection->GetXmppAuthenticationType()); 54 0 : bnr->set_send_ready(bx_channel->Peer()->send_ready()); 55 0 : bnr->set_flap_count(bx_channel->Peer()->peer_stats()->num_flaps()); 56 0 : bnr->set_flap_time(bx_channel->Peer()->peer_stats()->last_flap()); 57 : 58 0 : const XmppSession *sess = bx_channel->GetSession(); 59 0 : if (sess) { 60 0 : short int dscp = sess->GetDscpValue(); 61 0 : bnr->set_dscp_value(dscp); 62 : } 63 0 : if (summary) 64 0 : return; 65 : 66 0 : bnr->set_configured_hold_time(connection->GetConfiguredHoldTime()); 67 0 : bnr->set_configured_address_families(vector<string>()); 68 0 : bnr->set_negotiated_address_families(vector<string>()); 69 0 : const BgpMembershipManager *mgr = bsc->bgp_server->membership_mgr(); 70 0 : mgr->FillPeerMembershipInfo(bx_channel->Peer(), bnr); 71 0 : bx_channel->FillTableMembershipInfo(bnr); 72 0 : bx_channel->FillInstanceMembershipInfo(bnr); 73 0 : bx_channel->FillCloseInfo(bnr); 74 : 75 0 : BgpPeer::FillBgpNeighborDebugState(bnr, bx_channel->Peer()->peer_stats()); 76 : } 77 : 78 0 : static bool ShowXmppNeighbor(const BgpSandeshContext *bsc, bool summary, 79 : uint32_t page_limit, uint32_t iter_limit, const string &start_neighbor, 80 : const string &search_string, vector<BgpNeighborResp> *list, 81 : string *next_neighbor) { 82 0 : regex search_expr(search_string); 83 0 : const BgpXmppChannelManager *bxcm = bsc->xmpp_peer_manager; 84 : BgpXmppChannelManager::const_name_iterator it = 85 0 : bxcm->name_clower_bound(start_neighbor); 86 0 : for (uint32_t iter_count = 0; it != bxcm->name_cend(); ++it, ++iter_count) { 87 0 : const BgpXmppChannel *bx_channel = it->second; 88 0 : if (!ShowXmppNeighborMatch(bx_channel, search_string, search_expr)) 89 0 : continue; 90 0 : BgpNeighborResp bnr; 91 0 : FillXmppNeighborInfo(&bnr, bsc, bx_channel, summary); 92 0 : list->push_back(bnr); 93 0 : if (list->size() >= page_limit) 94 0 : break; 95 0 : if (iter_count >= iter_limit) 96 0 : break; 97 0 : } 98 : 99 : // All done if we've looked at all channels. 100 0 : if (it == bxcm->name_cend() || ++it == bxcm->name_cend()) 101 0 : return true; 102 : 103 : // Return true if we've reached the page limit, false if we've reached the 104 : // iteration limit. 105 0 : bool done = list->size() >= page_limit; 106 0 : *next_neighbor = it->second->ToString(); 107 0 : return done; 108 0 : } 109 : 110 0 : static void ShowXmppNeighborStatisticsVisitor( 111 : size_t *count, const BgpServer *bgp_server, string domain, 112 : string up_or_down, const BgpXmppChannel *channel) { 113 : 114 0 : if (boost::iequals(up_or_down, "up") && !channel->Peer()->IsReady()) { 115 0 : return; 116 : } 117 0 : if (boost::iequals(up_or_down, "down") && channel->Peer()->IsReady()) { 118 0 : return; 119 : } 120 : 121 0 : if (!domain.empty()) { 122 0 : const RoutingInstanceMgr *rim = bgp_server->routing_instance_mgr(); 123 0 : const RoutingInstance *ri = rim->GetRoutingInstance(domain); 124 0 : if (!ri) 125 0 : return; 126 0 : const BgpTable *table = ri->GetTable(Address::INET); 127 0 : if (!table) 128 0 : return; 129 : 130 0 : const BgpMembershipManager *mgr = bgp_server->membership_mgr(); 131 0 : if (!mgr->GetRegistrationInfo(channel->Peer(), table)) { 132 0 : return; 133 : } 134 : } 135 : 136 0 : ++*count; 137 : } 138 : 139 0 : static void ShowXmppNeighborStatistics( 140 : size_t *count, const BgpSandeshContext *bsc, 141 : const ShowNeighborStatisticsReq *req) { 142 0 : bsc->xmpp_peer_manager->VisitChannels( 143 0 : boost::bind(ShowXmppNeighborStatisticsVisitor, count, 144 0 : bsc->bgp_server, req->get_domain(), 145 0 : req->get_up_or_down(), _1)); 146 0 : } 147 : 148 0 : void RegisterSandeshShowXmppExtensions(BgpSandeshContext *bsc) { 149 0 : bsc->SetNeighborShowExtensions( 150 : &ShowXmppNeighbor, 151 : &ShowXmppNeighborStatistics); 152 0 : }