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