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