OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
peer_manager.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3  */
4 
6 
8 #include "base/address_util.h"
9 #include "bgp/bgp_factory.h"
10 #include "bgp/bgp_log.h"
11 #include "bgp/bgp_peer.h"
12 #include "bgp/bgp_peer_types.h"
13 #include "bgp/bgp_server.h"
16 
17 struct BgpSandeshContext;
18 
19 using std::make_pair;
20 using std::string;
21 using std::vector;
22 
23 //
24 // Find or create a BgpPeer for the given BgpNeighborConfig.
25 // Return NULL if the peer already exists and is being deleted. The BgpPeer
26 // will eventually get created in this case via PeerResurrect.
27 //
29  const BgpNeighborConfig *config) {
30  BgpPeerKey key(config);
31 
32  BgpPeerNameMap::iterator loc = peers_by_name_.find(config->name());
33  if (loc != peers_by_name_.end()) {
34  if (loc->second->IsDeleted())
35  return NULL;
36  RemovePeerByKey(loc->second->peer_key(), loc->second);
37  InsertPeerByKey(key, loc->second);
38  return loc->second;
39  }
40 
41  BgpPeer *peer =
42  BgpStaticObjectFactory::Create<BgpPeer>(server, instance(), config);
43  peer->Initialize();
44  InsertPeerByKey(key, peer);
45  InsertPeerByName(config->name(), peer);
46  RoutingInstanceInfo info = instance_->GetDataCollection("Add");
47  info.set_peer(peer->ToString());
49 
50  BGP_LOG_PEER(Config, peer, SandeshLevel::SYS_INFO, BGP_LOG_FLAG_ALL,
51  BGP_PEER_DIR_NA, "Created peer");
52  RTINSTANCE_LOG_PEER(Create, instance_, peer,
53  SandeshLevel::SYS_DEBUG, RTINSTANCE_LOG_FLAG_ALL);
54  return peer;
55 }
56 
57 //
58 // Resurrect the BgpPeer with given name if we have configuration for it.
59 // Also insert it into the BgpServer's EndpointPeerList - in case it is
60 // a BGPaaS peer. This needs to happen here since we would not have been
61 // able to do it from BgpServer::ConfigUpdater::ProcessNeighborConfig since
62 // old incarnation of the BgpPeer still existed at that point.
63 //
64 void PeerManager::PeerResurrect(string name) {
65  CHECK_CONCURRENCY("bgp::Config");
66 
67  if (instance_->deleted())
68  return;
69 
70  const BgpConfigManager *config_manager =
72  const BgpNeighborConfig *config =
73  config_manager->FindNeighbor(instance_->name(), name);
74  if (!config)
75  return;
76 
77  BgpPeer *peer = PeerLocate(server(), config);
78  assert(peer);
79  server()->InsertPeer(peer->endpoint(), peer);
80 }
81 
82 //
83 // Delete the BgpPeer corresponding to the given BgpNeighborConfig.
84 //
86  CHECK_CONCURRENCY("bgp::Config");
87 
88  BgpPeerNameMap::iterator loc = peers_by_name_.find(config->name());
89  if (loc == peers_by_name_.end())
90  return NULL;
91 
92  BgpPeer *peer = loc->second;
93  peer->ManagedDelete();
94 
95  RoutingInstanceInfo info = instance_->GetDataCollection("Delete");
96  info.set_peer(peer->ToString());
98 
99  RTINSTANCE_LOG_PEER(Delete, instance_, peer,
100  SandeshLevel::SYS_DEBUG, RTINSTANCE_LOG_FLAG_ALL);
101 
102  // Configuration is deleted by the config manager (parser)
103  // Do not hold reference to it any more
104  peer->ClearConfig();
105  return peer;
106 }
107 
108 //
109 // Concurrency: Called from bgp config task
110 //
111 // Complete the deletion process of a peer. Remove it from BgpPeerKeyMap and
112 // BgpPeerNameMap.
113 //
115  CHECK_CONCURRENCY("bgp::Config");
116 
117  BgpPeer *peer = static_cast<BgpPeer *>(ipeer);
118  string peer_name = peer->peer_name();
119  BGP_LOG_PEER(Config, peer, SandeshLevel::SYS_INFO, BGP_LOG_FLAG_ALL,
120  BGP_PEER_DIR_NA, "Destroyed peer");
121  RTINSTANCE_LOG_PEER(Destroy, instance_, peer,
122  SandeshLevel::SYS_DEBUG, RTINSTANCE_LOG_FLAG_ALL);
123  RemovePeerByKey(peer->peer_key(), peer);
124  RemovePeerByName(peer->peer_name(), peer);
125  delete peer;
126 
127  PeerResurrect(peer_name);
128 }
129 
130 //
131 // Insert the BgpPeer info the BgpPeerKeyMap.
132 //
134  peers_by_key_.insert(make_pair(key, peer));
135 }
136 
137 //
138 // Remove the BgpPeer from the BgpPeerKeyMap. There may be more than
139 // one BgpPeer with the same key, so we need to find the right one.
140 //
142  for (BgpPeerKeyMap::iterator loc = peers_by_key_.find(key);
143  loc != peers_by_key_.end() && loc->first == key; ++loc) {
144  if (loc->second == peer) {
145  peers_by_key_.erase(loc);
146  return;
147  }
148  }
149  assert(false);
150 }
151 
152 //
153 // Insert the BgpPeer info the BgpPeerNameMap.
154 //
155 void PeerManager::InsertPeerByName(const string name, BgpPeer *peer) {
156  peers_by_name_.insert(make_pair(name, peer));
157 }
158 
159 //
160 // Remove the BgpPeer from the BgpPeerNameMap.
161 //
162 void PeerManager::RemovePeerByName(const string name, BgpPeer *peer) {
163  BgpPeerNameMap::iterator loc = peers_by_name_.find(name);
164  assert(loc != peers_by_name_.end() && loc->second == peer);
165  peers_by_name_.erase(loc);
166 }
167 
168 BgpPeer *PeerManager::PeerFind(string ip_address) const {
169  if (ip_address.empty())
170  return NULL;
171 
172  boost::system::error_code ec;
173  boost::asio::ip::tcp::endpoint endpoint;
174  endpoint.address(AddressFromString(ip_address, &ec));
175  if (ec)
176  return NULL;
177 
178  return PeerLookup(endpoint);
179 }
180 
181 BgpPeer *PeerManager::PeerLookup(string name) const {
182  BgpPeerNameMap::const_iterator loc = peers_by_name_.find(name);
183  return (loc != peers_by_name_.end() ? loc->second : NULL);
184 }
185 
186 size_t PeerManager::GetNeighborCount(string up_or_down) {
187  size_t count = 0;
188  BgpPeerNameMap::iterator iter;
189 
190  for (iter = peers_by_name_.begin(); iter != peers_by_name_.end(); iter++) {
191  BgpPeer *peer = iter->second;
192  if (boost::iequals(up_or_down, "up") && !peer->IsReady())
193  continue;
194  if (boost::iequals(up_or_down, "down") && peer->IsReady())
195  continue;
196  count += 1;
197  }
198 
199  return count;
200 }
201 
203  BgpPeerNameMap::iterator iter;
204 
205  for (iter = peers_by_name_.begin(); iter != peers_by_name_.end(); iter++) {
206  BgpPeer *peer = iter->second;
208  }
209 }
210 
212  BgpPeerNameMap::iterator iter;
213 
214  for (iter = peers_by_name_.begin(); iter != peers_by_name_.end(); iter++) {
215  BgpPeer *peer = iter->second;
216  if (peer->PeerType() == BgpProto::IBGP)
218  }
219 }
220 
221 //
222 // Concurrency: Called from state machine thread
223 //
225  BgpPeer *peer = NULL;
226  BgpPeerKey peer_key;
227 
228  // Bail if the instance is undergoing deletion.
229  if (instance_->deleted())
230  return NULL;
231 
232  peer_key.endpoint.address(remote_endpoint.address());
233 
234  // Do a partial match, as we do not know the peer's port yet.
235  BgpPeerKeyMap::const_iterator loc = peers_by_key_.lower_bound(peer_key);
236  while (loc != peers_by_key_.end()) {
237  // Check if the address does indeed match as we are doing a partial
238  // match here
239  if (loc->second->peer_key().endpoint.address() !=
240  peer_key.endpoint.address()) {
241  break;
242  }
243 
244  // This peer certainly matches with the IP address. If we do not find
245  // an exact match with the peer-id, then just use this.
246  peer = loc->second;
247  break;
248  }
249 
250  return peer;
251 }
252 
253 const BgpPeer *PeerManager::NextPeer(const BgpPeerKey &peer_key) const {
254  // Do a partial match
255  BgpPeerKeyMap::const_iterator loc = peers_by_key_.upper_bound(peer_key);
256  if (loc != peers_by_key_.end()) {
257  return loc->second;
258  }
259 
260  return NULL;
261 }
262 
263 const string &PeerManager::name() const {
264  return instance_->name();
265 }
266 
268  return instance_->server();
269 }
boost::asio::ip::tcp::endpoint Endpoint
Definition: tcp_session.h:62
void ClearAllInternalPeers()
void Initialize()
Definition: bgp_peer.cc:652
virtual BgpPeer * PeerLookup(std::string name) const
const std::string & name() const
Definition: bgp_config.h:162
#define RTINSTANCE_LOG_PEER(type, rtinstance, peer, level, flags,...)
BgpPeerNameMap peers_by_name_
Definition: peer_manager.h:65
BgpServer * server()
BgpPeer * TriggerPeerDeletion(const BgpNeighborConfig *config)
Definition: peer_manager.cc:85
virtual BgpPeer * PeerFind(std::string address) const
const std::string & name() const
const std::string & name() const
virtual BgpProto::BgpPeerType PeerType() const
Definition: bgp_peer.h:208
RoutingInstanceInfo GetDataCollection(const char *operation)
BgpServer * server()
Definition: ipeer.h:186
boost::asio::ip::tcp::endpoint endpoint
Definition: bgp_peer_key.h:24
virtual const std::string & ToString() const
Definition: bgp_peer.h:100
const BgpPeer * NextPeer(const BgpPeerKey &key) const
const BgpPeerKey & peer_key() const
Definition: bgp_peer.h:164
const RoutingInstance * instance() const
Definition: peer_manager.h:48
void PeerResurrect(std::string name)
Definition: peer_manager.cc:64
const std::string & peer_name() const
Definition: bgp_peer.h:168
BgpConfigManager * config_manager()
Definition: bgp_server.h:100
#define RTINSTANCE_LOG_FLAG_ALL
#define CHECK_CONCURRENCY(...)
void ManagedDelete()
Definition: bgp_peer.cc:2364
virtual const BgpNeighborConfig * FindNeighbor(const std::string &instance_name, const std::string &name) const =0
void InsertPeer(TcpSession::Endpoint remote, BgpPeer *peer)
Definition: bgp_server.cc:639
const RoutingInstanceMgr * manager() const
#define ROUTING_INSTANCE_COLLECTOR_INFO(info)
IpAddress AddressFromString(const std::string &ip_address_str, boost::system::error_code *ec)
void RemovePeerByKey(BgpPeerKey key, BgpPeer *peer)
virtual bool IsReady() const
Definition: bgp_peer.cc:1207
void InsertPeerByName(const std::string name, BgpPeer *peer)
void RemovePeerByName(const std::string name, BgpPeer *peer)
void ClearAllPeers()
void ClearConfig()
Definition: bgp_peer.cc:1162
virtual BgpPeer * PeerLocate(BgpServer *server, const BgpNeighborConfig *config)
Definition: peer_manager.cc:28
BgpServer * server() const
bool deleted() const
BgpPeerKeyMap peers_by_key_
Definition: peer_manager.h:64
TcpSession::Endpoint endpoint() const
Definition: bgp_peer.h:171
virtual void DestroyIPeer(IPeer *ipeer)
void Clear(int subcode)
Definition: bgp_peer.cc:1306
#define BGP_LOG_FLAG_ALL
Definition: bgp_log.h:44
#define BGP_LOG_PEER(type, peer, level, flags, dir, arg)
Definition: bgp_log.h:159
#define BGP_PEER_DIR_NA
Definition: bgp_log.h:140
RoutingInstance * instance_
Definition: peer_manager.h:66
size_t GetNeighborCount(std::string up_or_down)
void InsertPeerByKey(BgpPeerKey key, BgpPeer *peer)