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 "bgp/bgp_show_handler.h" 7 : 8 : #include <boost/foreach.hpp> 9 : 10 : #include "base/regex.h" 11 : #include "bgp/bgp_config_ifmap.h" 12 : #include "bgp/bgp_peer_types.h" 13 : #include "bgp/bgp_peer_internal_types.h" 14 : #include "bgp/bgp_server.h" 15 : #include "schema/bgp_schema_types.h" 16 : 17 : using contrail::regex; 18 : using contrail::regex_match; 19 : using contrail::regex_search; 20 : using std::string; 21 : using std::vector; 22 : 23 : // 24 : // Fill in information for a peering. 25 : // 26 6 : static void FillBgpPeeringConfigInfo(ShowBgpPeeringConfig *sbpc, 27 : const BgpSandeshContext *bsc, const BgpIfmapPeeringConfig *peering) { 28 6 : sbpc->set_instance_name(peering->instance()->name()); 29 6 : sbpc->set_name(peering->name()); 30 6 : sbpc->set_neighbor_count(peering->size()); 31 6 : if (peering->bgp_peering()) { 32 6 : vector<ShowBgpSessionConfig> sbsc_list; 33 6 : for (vector<autogen::BgpSession>::const_iterator sit = 34 6 : peering->bgp_peering()->data().begin(); 35 11 : sit != peering->bgp_peering()->data().end(); ++sit) { 36 5 : ShowBgpSessionConfig sbsc; 37 5 : sbsc.set_uuid(sit->uuid); 38 5 : vector<ShowBgpSessionAttributesConfig> sbsac_list; 39 5 : for (vector<autogen::BgpSessionAttributes>::const_iterator ait = 40 20 : sit->attributes.begin(); ait != sit->attributes.end(); ++ait) { 41 10 : ShowBgpSessionAttributesConfig sbsac; 42 10 : sbsac.set_bgp_router(ait->bgp_router); 43 10 : sbsac.set_address_families(ait->address_families.family); 44 10 : sbsac_list.push_back(sbsac); 45 10 : } 46 5 : sbsc.set_attributes(sbsac_list); 47 5 : sbsc_list.push_back(sbsc); 48 5 : } 49 6 : sbpc->set_sessions(sbsc_list); 50 6 : } 51 6 : } 52 : 53 : // 54 : // Specialization of BgpShowHandler<>::CallbackCommon. 55 : // 56 : template <> 57 3 : bool BgpShowHandler<ShowBgpPeeringConfigReq, ShowBgpPeeringConfigReqIterate, 58 : ShowBgpPeeringConfigResp, ShowBgpPeeringConfig>::CallbackCommon( 59 : const BgpSandeshContext *bsc, Data *data) { 60 3 : uint32_t page_limit = bsc->page_limit() ? bsc->page_limit() : kPageLimit; 61 3 : uint32_t iter_limit = bsc->iter_limit() ? bsc->iter_limit() : kIterLimit; 62 3 : const BgpIfmapConfigManager *bcm = dynamic_cast<BgpIfmapConfigManager *>( 63 3 : bsc->bgp_server->config_manager()); 64 3 : if (!bcm) 65 0 : return true; 66 : 67 3 : regex search_expr(data->search_string); 68 : BgpConfigManager::InstanceMapRange range = 69 3 : bcm->InstanceMapItems(data->next_entry); 70 3 : BgpConfigManager::InstanceMap::const_iterator it = range.first; 71 3 : BgpConfigManager::InstanceMap::const_iterator it_end = range.second; 72 10 : for (uint32_t iter_count = 0; it != it_end; ++it, ++iter_count) { 73 : const BgpIfmapInstanceConfig *instance = 74 7 : bcm->config()->FindInstance(it->first); 75 7 : if (!instance) 76 0 : continue; 77 19 : BOOST_FOREACH(BgpIfmapInstanceConfig::PeeringMap::value_type value, 78 : instance->peerings()) { 79 6 : const BgpIfmapPeeringConfig *peering = value.second; 80 6 : if (!regex_search(peering->name(), search_expr)) 81 0 : continue; 82 6 : ShowBgpPeeringConfig sbpc; 83 6 : FillBgpPeeringConfigInfo(&sbpc, bsc, peering); 84 6 : data->show_list.push_back(sbpc); 85 12 : } 86 7 : if (data->show_list.size() >= page_limit) 87 0 : break; 88 7 : if (iter_count >= iter_limit) 89 0 : break; 90 : } 91 : 92 : // All done if we've looked at all instances. 93 3 : if (it == it_end || ++it == it_end) 94 3 : return true; 95 : 96 : // Return true if we've reached the page limit, false if we've reached the 97 : // iteration limit. 98 0 : bool done = data->show_list.size() >= page_limit; 99 0 : SaveContextToData(it->second->name(), done, data); 100 0 : return done; 101 3 : } 102 : 103 : // 104 : // Specialization of BgpShowHandler<>::FillShowList. 105 : // 106 : template <> 107 3 : void BgpShowHandler<ShowBgpPeeringConfigReq, ShowBgpPeeringConfigReqIterate, 108 : ShowBgpPeeringConfigResp, ShowBgpPeeringConfig>::FillShowList( 109 : ShowBgpPeeringConfigResp *resp, 110 : const vector<ShowBgpPeeringConfig> &show_list) { 111 3 : resp->set_peerings(show_list); 112 3 : } 113 : 114 : // 115 : // Handler for ShowBgpPeeringConfigReq. 116 : // Called via BgpSandeshContext::PeeringShowReqHandler. 117 : // 118 3 : void ShowBgpIfmapPeeringConfigReqHandler(const BgpSandeshContext *bsc, 119 : const ShowBgpPeeringConfigReq *req) { 120 3 : RequestPipeline::PipeSpec ps(req); 121 3 : RequestPipeline::StageSpec s1; 122 3 : TaskScheduler *scheduler = TaskScheduler::GetInstance(); 123 : 124 3 : s1.taskId_ = scheduler->GetTaskId("bgp::ShowCommand"); 125 : s1.cbFn_ = boost::bind(&BgpShowHandler< 126 : ShowBgpPeeringConfigReq, 127 : ShowBgpPeeringConfigReqIterate, 128 : ShowBgpPeeringConfigResp, 129 3 : ShowBgpPeeringConfig>::Callback, _1, _2, _3, _4, _5); 130 : s1.allocFn_ = BgpShowHandler< 131 : ShowBgpPeeringConfigReq, 132 : ShowBgpPeeringConfigReqIterate, 133 : ShowBgpPeeringConfigResp, 134 3 : ShowBgpPeeringConfig>::CreateData; 135 3 : s1.instances_.push_back(0); 136 3 : ps.stages_.push_back(s1); 137 3 : RequestPipeline rp(ps); 138 3 : } 139 : 140 : // 141 : // Handler for ShowBgpPeeringConfigReqIterate. 142 : // Called via BgpSandeshContext::PeeringShowReqIterateHandler. 143 : // 144 0 : void ShowBgpIfmapPeeringConfigReqIterateHandler(const BgpSandeshContext *bsc, 145 : const ShowBgpPeeringConfigReqIterate *req_iterate) { 146 0 : RequestPipeline::PipeSpec ps(req_iterate); 147 0 : RequestPipeline::StageSpec s1; 148 0 : TaskScheduler *scheduler = TaskScheduler::GetInstance(); 149 : 150 0 : s1.taskId_ = scheduler->GetTaskId("bgp::ShowCommand"); 151 : s1.cbFn_ = boost::bind(&BgpShowHandler< 152 : ShowBgpPeeringConfigReq, 153 : ShowBgpPeeringConfigReqIterate, 154 : ShowBgpPeeringConfigResp, 155 0 : ShowBgpPeeringConfig>::CallbackIterate, _1, _2, _3, _4, _5); 156 : s1.allocFn_ = BgpShowHandler< 157 : ShowBgpPeeringConfigReq, 158 : ShowBgpPeeringConfigReqIterate, 159 : ShowBgpPeeringConfigResp, 160 0 : ShowBgpPeeringConfig>::CreateData; 161 0 : s1.instances_.push_back(0); 162 0 : ps.stages_.push_back(s1); 163 0 : RequestPipeline rp(ps); 164 0 : }