Line data Source code
1 : /* 2 : * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved. 3 : */ 4 : 5 : #include "bgp/routing-instance/rtarget_group.h" 6 : 7 : #include <boost/assign/list_of.hpp> 8 : #include <boost/foreach.hpp> 9 : 10 : #include <utility> 11 : 12 : #include "sandesh/sandesh_trace.h" 13 : #include "bgp/bgp_peer.h" 14 : #include "bgp/bgp_peer_types.h" 15 : #include "bgp/bgp_table.h" 16 : #include "bgp/rtarget/rtarget_route.h" 17 : #include "db/db.h" 18 : 19 : using boost::assign::list_of; 20 : using std::pair; 21 : using std::string; 22 : using std::vector; 23 : 24 108894 : RtGroup::RtGroup(const RouteTarget &rt) 25 108894 : : rt_(rt), dep_(RTargetDepRouteList(DB::PartitionCount())) { 26 : vector<Address::Family> vpn_family_list = list_of 27 108894 : (Address::INETVPN)(Address::INET6VPN)(Address::ERMVPN)(Address::EVPN) 28 108894 : (Address::MVPN); 29 1197830 : BOOST_FOREACH(Address::Family vpn_family, vpn_family_list) { 30 544468 : import_[vpn_family] = RtGroupMemberList(); 31 544469 : export_[vpn_family] = RtGroupMemberList(); 32 : } 33 108894 : } 34 : 35 325794 : bool RtGroup::MayDelete() const { 36 325794 : return !HasImportExportTables() && !HasInterestedPeers() && !HasDepRoutes(); 37 : } 38 : 39 2114212 : const RtGroup::RtGroupMemberList &RtGroup::GetImportTables( 40 : Address::Family family) const { 41 2114212 : return import_.at(family); 42 : } 43 : 44 1379754 : const RtGroup::RtGroupMemberList &RtGroup::GetExportTables( 45 : Address::Family family) const { 46 1379754 : return export_.at(family); 47 : } 48 : 49 1119425 : bool RtGroup::AddImportTable(Address::Family family, BgpTable *tbl) { 50 1119425 : bool first = import_[family].empty(); 51 1119087 : import_[family].insert(tbl); 52 1119624 : return first; 53 : } 54 : 55 668280 : bool RtGroup::AddExportTable(Address::Family family, BgpTable *tbl) { 56 668280 : bool first = export_[family].empty(); 57 668116 : export_[family].insert(tbl); 58 668329 : return first; 59 : } 60 : 61 1119668 : bool RtGroup::RemoveImportTable(Address::Family family, BgpTable *tbl) { 62 1119668 : import_[family].erase(tbl); 63 1119660 : return import_[family].empty(); 64 : } 65 : 66 668345 : bool RtGroup::RemoveExportTable(Address::Family family, BgpTable *tbl) { 67 668345 : export_[family].erase(tbl); 68 668345 : return export_[family].empty(); 69 : } 70 : 71 325794 : bool RtGroup::HasImportExportTables() const { 72 1686524 : BOOST_FOREACH(const RtGroupMembers::value_type &family_members, import_) { 73 870086 : if (!family_members.second.empty()) 74 189721 : return true; 75 : } 76 1496803 : BOOST_FOREACH(const RtGroupMembers::value_type &family_members, export_) { 77 680365 : if (!family_members.second.empty()) 78 0 : return true; 79 : } 80 136073 : return false; 81 : } 82 : 83 928554 : bool RtGroup::HasVrfTables(Address::Family family) const { 84 : const BgpTable *table; 85 : 86 928554 : const RtGroupMemberList &import_list = import_.at(family); 87 928553 : if (import_list.size() > 1) 88 307805 : return true; 89 620749 : table = *import_list.begin(); 90 620749 : if (table && !table->IsVpnTable()) 91 0 : return true; 92 : 93 620750 : const RtGroupMemberList &export_list = export_.at(family); 94 620749 : if (export_list.size() > 1) 95 190655 : return true; 96 430094 : table = *export_list.begin(); 97 430094 : if (table && !table->IsVpnTable()) 98 185 : return true; 99 : 100 429909 : return false; 101 : } 102 : 103 2215729 : const RouteTarget &RtGroup::rt() { 104 2215729 : return rt_; 105 : } 106 : 107 500007 : void RtGroup::AddDepRoute(int part_id, BgpRoute *rt) { 108 500007 : dep_[part_id].insert(rt); 109 500010 : } 110 : 111 500009 : void RtGroup::RemoveDepRoute(int part_id, BgpRoute *rt) { 112 500009 : dep_[part_id].erase(rt); 113 499956 : } 114 : 115 269316 : void RtGroup::NotifyDepRoutes(int part_id) { 116 1239985 : BOOST_FOREACH(BgpRoute *route, dep_[part_id]) { 117 484606 : DBTablePartBase *dbpart = route->get_table_partition(); 118 484419 : dbpart->Notify(route); 119 : } 120 268907 : } 121 : 122 1514478 : bool RtGroup::HasDepRoutes() const { 123 1514478 : for (RTargetDepRouteList::const_iterator it = dep_.begin(); 124 6886990 : it != dep_.end(); ++it) { 125 5530728 : if (!it->empty()) { 126 158158 : return true; 127 : } 128 : } 129 1356165 : return false; 130 : } 131 : 132 2236595 : const RtGroupInterestedPeerSet& RtGroup::GetInterestedPeers() const { 133 2236595 : return interested_peers_; 134 : } 135 : 136 27192 : void RtGroup::AddInterestedPeer(const BgpPeer *peer, RTargetRoute *rt) { 137 27192 : InterestedPeerList::iterator it = peer_list_.find(peer); 138 27192 : if (it == peer_list_.end()) { 139 23616 : it = peer_list_.insert(peer_list_.begin(), 140 47232 : pair<const BgpPeer *, RTargetRouteList>(peer, RTargetRouteList())); 141 23616 : assert(peer->GetIndex() >= 0); 142 23616 : interested_peers_.set(peer->GetIndex()); 143 : } 144 27192 : it->second.insert(rt); 145 27192 : } 146 : 147 27192 : void RtGroup::RemoveInterestedPeer(const BgpPeer *peer, RTargetRoute *rt) { 148 27192 : InterestedPeerList::iterator it = peer_list_.find(peer); 149 27192 : if (it == peer_list_.end()) return; 150 27192 : it->second.erase(rt); 151 27192 : if (it->second.empty()) { 152 23616 : peer_list_.erase(peer); 153 23616 : assert(peer->GetIndex() >= 0); 154 23616 : interested_peers_.reset(peer->GetIndex()); 155 : } 156 : } 157 : 158 136073 : bool RtGroup::HasInterestedPeers() const { 159 136073 : return !peer_list_.empty(); 160 : } 161 : 162 106 : bool RtGroup::HasInterestedPeer(const string &name) const { 163 242 : BOOST_FOREACH(const InterestedPeerList::value_type &peer, peer_list_) { 164 92 : if (peer.first->peer_basename() == name) 165 24 : return true; 166 : } 167 82 : return false; 168 : } 169 : 170 3942 : void RtGroup::FillMemberTables(const RtGroupMembers &rt_members, 171 : vector<ShowRtGroupMemberTableList> *member_list) const { 172 43362 : BOOST_FOREACH(const RtGroupMembers::value_type &rt_tables, rt_members) { 173 19710 : ShowRtGroupMemberTableList member; 174 19710 : vector<string> table_names; 175 93870 : BOOST_FOREACH(BgpTable *table, rt_tables.second) { 176 37080 : table_names.push_back(table->name()); 177 : } 178 19710 : member.set_family(Address::FamilyToString(rt_tables.first)); 179 19710 : member.set_tables(table_names); 180 19710 : member_list->push_back(member); 181 19710 : } 182 3942 : } 183 : 184 1947 : void RtGroup::FillInterestedPeers(vector<string> *interested_peers) const { 185 2155 : BOOST_FOREACH(const InterestedPeerList::value_type &peer, peer_list_) { 186 104 : interested_peers->push_back(peer.first->peer_basename()); 187 : } 188 1947 : } 189 : 190 1909 : void RtGroup::FillDependentRoutes(vector<string> *rtlist) const { 191 1909 : for (RTargetDepRouteList::const_iterator dep_it = dep_.begin(); 192 9545 : dep_it != dep_.end(); ++dep_it) { 193 7636 : for (RouteList::const_iterator dep_rt_it = dep_it->begin(); 194 7655 : dep_rt_it != dep_it->end(); ++dep_rt_it) { 195 19 : rtlist->push_back((*dep_rt_it)->ToString()); 196 : } 197 : } 198 1909 : } 199 : 200 1971 : void RtGroup::FillShowInfoCommon(ShowRtGroupInfo *info, 201 : bool fill_peers, bool fill_routes) const { 202 1971 : info->set_rtarget(ToString()); 203 : 204 1971 : vector<ShowRtGroupMemberTableList> import_members; 205 1971 : FillMemberTables(import_, &import_members); 206 1971 : info->set_import_members(import_members); 207 1971 : vector<ShowRtGroupMemberTableList> export_members; 208 1971 : FillMemberTables(export_, &export_members); 209 1971 : info->set_export_members(export_members); 210 : 211 1971 : if (fill_peers) { 212 1947 : vector<string> interested_peers; 213 1947 : FillInterestedPeers(&interested_peers); 214 1947 : info->set_peers_interested(interested_peers); 215 1947 : } 216 1971 : if (fill_routes) { 217 1909 : vector<string> rtlist; 218 1909 : FillDependentRoutes(&rtlist); 219 1909 : info->set_dep_route(rtlist); 220 1909 : } 221 1971 : } 222 : 223 1885 : void RtGroup::FillShowInfo(ShowRtGroupInfo *info) const { 224 1885 : FillShowInfoCommon(info, true, true); 225 1885 : } 226 : 227 62 : void RtGroup::FillShowSummaryInfo(ShowRtGroupInfo *info) const { 228 62 : FillShowInfoCommon(info, true, false); 229 62 : } 230 : 231 24 : void RtGroup::FillShowPeerInfo(ShowRtGroupInfo *info) const { 232 24 : FillShowInfoCommon(info, false, true); 233 24 : }