OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
peer.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3  */
4 
5 #include <cmn/agent_cmn.h>
6 #include <oper/vrf.h>
7 #include <oper/route_common.h>
8 #include <oper/peer.h>
10 #include <oper/mirror_table.h>
11 
17 
18 Peer::Peer(Type type, const std::string &name, bool export_to_controller) :
19  type_(type), name_(name), export_to_controller_(export_to_controller) {
20  refcount_ = 0;
21  sequence_number_ = 0;
22 }
23 
25 }
26 
28  return false;
29 }
30 
31 void intrusive_ptr_add_ref(const Peer *p) {
32  p->refcount_.fetch_and_increment();
33  // validate that reference is not taken while delete is in progress
34  assert(!p->IsDeleted());
35 }
36 
37 void intrusive_ptr_release(const Peer *p) {
38  if (p->refcount_.fetch_and_decrement() == 1 && p->DeleteOnZeroRefcount()) {
39  delete p;
40  }
41 }
42 
43 DynamicPeer::DynamicPeer(Agent *agent, Type type, const std::string &name,
44  bool export_to_controller) :
45  Peer(type, name, export_to_controller) {
47  *(agent->event_manager())->io_service(),
48  "Dynamic Peer Delete Timer",
49  agent->task_scheduler()->\ GetTaskId("db::DBTable"), 0);
50  deleted_ = false;
51  skip_add_change_ = false;
52 }
53 
55  // Dynamic Peer should be marked deleted and will free
56  // automatically once all the references go away
57  assert(deleted_);
58  assert(refcount() == 0);
60 }
61 
64 
65  if (p->deleted_.fetch_and_store(true)) {
66  return;
67  }
68 
69  if (p->refcount() != 0) {
70  // still pending references are there start delete timeout timer
72  boost::bind(&DynamicPeer::DeleteTimeout,
73  p));
74  return;
75  }
76 
77  // no pending references delete the peer inline and return
78  delete p;
79 }
80 
82  assert(0);
83  return false;
84 }
85 
87  if (!deleted_) {
88  return false;
89  }
90 
91  // last reference has gone, cancel the timer and delete peer
93 
94  return true;
95 }
96 
97 const Ip4Address *Peer::NexthopIp(Agent *agent, const AgentPath *path) const {
98  return agent->router_ip_ptr();
99 }
100 
101 BgpPeer::BgpPeer(AgentXmppChannel *channel, const Ip4Address &server_ip,
102  const std::string &name, DBTableBase::ListenerId id,
103  Peer::Type bgp_peer_type) :
104  DynamicPeer(channel->agent(), bgp_peer_type, name, false),
105  channel_(channel), server_ip_(server_ip), id_(id),
106  delete_stale_walker_(NULL), route_walker_cb_(NULL),
107  delete_stale_walker_cb_(NULL) {
112 }
113 
115  const Agent *agent = route_walker()->agent();
116  // TODO verify if this unregister can be done in walkdone callback
117  // for delpeer
118  if ((id_ != -1) && agent->vrf_table()) {
119  agent->vrf_table()->Unregister(id_);
120  }
124 }
125 
126 // Route notify walker routines
128  if (!route_walker()) {
129  Agent *agent = channel_->agent();
131  this);
132  agent->oper_db()->agent_route_walk_manager()->
133  RegisterWalker(static_cast<AgentRouteWalker *>
134  (route_walker_.get()));
135  }
136 }
137 
139  if (!route_walker()) {
140  return;
141  }
142 
143  Agent *agent = Agent::GetInstance();
145  route_walker_.reset();
146 }
147 
148 void BgpPeer::PeerNotifyRoutes(WalkDoneCb cb) {
152 }
153 
155  //No implementation of stop, to stop a walk release walker. Re-allocate for
156  //further use.
159 }
160 
161 void BgpPeer::PeerNotifyMulticastRoutes(bool associate) {
163  NULL);
164 }
165 
166 // Delete stale walker routines
169  Agent *agent = channel_->agent();
171  this);
172  agent->oper_db()->agent_route_walk_manager()->
173  RegisterWalker(static_cast<AgentRouteWalker *>
174  (delete_stale_walker_.get()));
175  }
176 }
177 
180  return;
181  }
182 
183  Agent *agent = Agent::GetInstance();
184  agent->oper_db()->agent_route_walk_manager()->
185  ReleaseWalker(delete_stale_walker());
186  delete_stale_walker_.reset();
187 }
188 
189 // Delete stale walker routines
192  Agent *agent = channel_->agent();
194  this);
195  agent->oper_db()->agent_route_walk_manager()->
196  RegisterWalker(static_cast<AgentRouteWalker *>
197  (delete_peer_walker_.get()));
198  }
199 }
200 
203  return;
204  }
205 
206  Agent *agent = Agent::GetInstance();
207  agent->oper_db()->agent_route_walk_manager()->
208  ReleaseWalker(delete_peer_walker());
209  delete_peer_walker_.reset();
210 }
211 
212 void BgpPeer::DelPeerRoutes(WalkDoneCb walk_done_cb,
213  uint64_t sequence_number) {
214  //Since peer is getting deleted no need of seperate walk to delete stale or
215  //non stale paths.
217  delete_peer_walker_cb_ = walk_done_cb;
218  delete_peer_walker()->set_sequence_number(sequence_number);
221 }
222 
223 void BgpPeer::DeleteStale() {
224  //If peer is marked for deletion skip. Deletion should take care of removing
225  //routes.
226  if (SkipAddChangeRequest())
227  return;
228 
232 }
233 
235  //No implementation of stop, to stop a walk release walker. Re-allocate for
236  //further use.
239 }
240 
242  return static_cast<ControllerRouteWalker *>(route_walker_.get());
243 }
244 
246  return static_cast<ControllerRouteWalker *>(delete_stale_walker_.get());
247 }
248 
250  return static_cast<ControllerRouteWalker *>(delete_peer_walker_.get());
251 }
252 /*
253  * Get the VRF state and unregister from all route table using
254  * rt_export listener id. This will be called for active and non active bgp
255  * peers. In case of active bgp peers send unsubscribe to control node(request
256  * came via vrf delete).
257  */
259  DBEntryBase *entry) {
260  VrfEntry *vrf = static_cast<VrfEntry *>(entry);
261 
263  VrfExport::State *vrf_state = static_cast<VrfExport::State *>
264  (GetVrfExportState(partition, entry));
265 
266  if (vrf_state == NULL)
267  return;
268 
269  for (uint8_t table_type = (Agent::INVALID + 1);
270  table_type < Agent::ROUTE_TABLE_MAX; table_type++) {
271  if (vrf_state->rt_export_[table_type])
272  vrf_state->rt_export_[table_type]->Unregister();
273  }
274 
275  if (vrf_state->exported_ == true) {
276  // Check if the notification is for active bgp peer or not.
277  // Send unsubscribe only for active bgp peer.
278  // If skip_add_change is set for this dynamic peer, then dont export.
279  if (SkipAddChangeRequest() == false) {
281  vrf,
282  false);
283  }
284  }
285 
286  vrf->ClearState(partition->parent(), id);
287  delete vrf_state;
288 
289  return;
290 }
291 
292 // For given peer return the dbstate for given VRF and partition
294  DBEntryBase *entry) {
296  VrfEntry *vrf = static_cast<VrfEntry *>(entry);
297  return (static_cast<VrfExport::State *>(vrf->GetState(partition->parent(),
298  id)));
299 }
300 
301 // For given route return the dbstate for given partiton
303  DBEntryBase *entry) {
304  AgentRoute *route = static_cast<AgentRoute *>(entry);
305  VrfEntry *vrf = route->vrf();
306 
307  DBTablePartBase *vrf_partition = agent()->vrf_table()->
308  GetTablePartition(vrf);
309 
310  VrfExport::State *vs = static_cast<VrfExport::State *>
311  (GetVrfExportState(vrf_partition, vrf));
312 
313  if (vs == NULL)
314  return NULL;
315 
316  Agent::RouteTableType table_type = route->GetTableType();
317  RouteExport::State *state = NULL;
318  if (vs->rt_export_[table_type]) {
319  state = static_cast<RouteExport::State *>(route->GetState(partition->
320  parent(),
321  vs->rt_export_[table_type]->GetListenerId()));
322  }
323  return state;
324 }
325 
326 Agent *BgpPeer::agent() const {
327  return channel_->agent();
328 }
329 
331  return channel_;
332 }
333 
334 uint64_t BgpPeer::ChannelSequenceNumber() const {
336 }
337 
338 void BgpPeer::set_route_walker_cb(WalkDoneCb cb) {
340 }
341 
342 void BgpPeer::set_delete_stale_walker_cb(WalkDoneCb cb) {
344 }
345 void BgpPeer::set_delete_peer_walker_cb(WalkDoneCb cb) {
347 }
348 
void set_delete_stale_walker_cb(WalkDoneCb cb)
Definition: peer.cc:343
void StopDeleteStale()
Definition: peer.cc:235
tbb::atomic< uint32_t > refcount_
Definition: peer.h:106
void PeerNotifyMulticastRoutes(bool associate)
Definition: peer.cc:162
int intrusive_ptr_add_ref(const AsPath *cpath)
Definition: bgp_aspath.h:147
void ReleaseDeletePeerWalker()
Definition: peer.cc:202
static Agent * GetInstance()
Definition: agent.h:436
Agent * agent() const
Definition: vrf.h:86
Ip4Address server_ip_
Definition: peer.h:211
virtual bool SkipAddChangeRequest() const
Definition: peer.h:131
DBState * GetState(DBTableBase *tbl_base, ListenerId listener) const
Definition: db_entry.cc:37
WalkDoneCb route_walker_cb_
Definition: peer.h:217
void DeleteStale()
Definition: peer.cc:224
Timer * delete_timeout_timer_
Definition: peer.h:149
DynamicPeer(Agent *agent, Type type, const std::string &name, bool controller_export)
Definition: peer.cc:43
void ReleaseDeleteStaleWalker()
Definition: peer.cc:179
int ListenerId
Definition: db_table.h:62
void DelPeerRoutes(WalkDoneCb walk_done_cb, uint64_t sequence_number)
Definition: peer.cc:213
void AllocDeletePeerWalker()
Definition: peer.cc:191
ControllerRouteWalker * delete_peer_walker() const
Definition: peer.cc:250
DBTableBase * parent()
AgentRouteWalkerPtr route_walker_
Definition: peer.h:214
void set_route_walker_cb(WalkDoneCb cb)
Definition: peer.cc:339
virtual ~Peer()
Definition: peer.cc:24
void AllocPeerNotifyWalker()
Definition: peer.cc:128
WalkDoneCb delete_stale_walker_cb_
Definition: peer.h:218
virtual bool DeleteOnZeroRefcount() const
Definition: peer.cc:27
DBState * GetRouteExportState(DBTablePartBase *partition, DBEntryBase *e)
Definition: peer.cc:303
void set_sequence_number(uint64_t sequence_number)
virtual bool DeleteOnZeroRefcount() const
Definition: peer.cc:87
Peer(Type type, const std::string &name, bool controller_export)
Definition: peer.cc:18
Base class for all Route entries in agent.
Definition: agent_route.h:224
bool DeleteTimeout()
Definition: peer.cc:82
DBTableBase::ListenerId GetListenerId() const
void Unregister(ListenerId listener)
Definition: db_table.cc:186
uint64_t ChannelSequenceNumber() const
Definition: peer.cc:335
OperDB * oper_db() const
Definition: agent.cc:1013
virtual bool IsDeleted() const
Definition: peer.h:91
BgpPeer(BgpServer *server, RoutingInstance *instance, const BgpNeighborConfig *config)
Definition: bgp_peer.cc:469
DBTableBase::ListenerId id_
Definition: peer.h:212
virtual const Ip4Address * NexthopIp(Agent *agent, const AgentPath *path) const
Definition: peer.cc:98
virtual Agent::RouteTableType GetTableType() const =0
void StopPeerNotifyRoutes()
Definition: peer.cc:155
TaskScheduler * task_scheduler() const
Definition: agent.h:1120
uint8_t type
Definition: load_balance.h:109
Definition: agent.h:358
AgentRouteWalkerManager * agent_route_walk_manager() const
Definition: operdb_init.h:91
void PeerNotifyRoutes(WalkDoneCb cb)
Definition: peer.cc:149
uint64_t sequence_number() const
EventManager * event_manager() const
Definition: agent.h:1103
AgentRouteWalkerPtr delete_peer_walker_
Definition: peer.h:215
DBTableBase::ListenerId GetVrfExportListenerId()
Definition: peer.h:171
uint64_t sequence_number() const
Definition: peer.h:94
ControllerRouteWalker * route_walker() const
Definition: peer.cc:242
tbb::atomic< bool > skip_add_change_
Definition: peer.h:151
AgentXmppChannel * GetAgentXmppChannel() const
Definition: peer.cc:331
tbb::atomic< bool > deleted_
Definition: peer.h:150
DBState * GetVrfExportState(DBTablePartBase *partition, DBEntryBase *e)
Definition: peer.cc:294
void DeleteVrfState(DBTablePartBase *partition, DBEntryBase *entry)
Definition: peer.cc:259
Definition: peer.h:44
virtual ~BgpPeer()
Definition: bgp_peer.cc:625
static Timer * CreateTimer(boost::asio::io_context &service, const std::string &name, int task_id=Timer::GetTimerTaskId(), int task_instance=Timer::GetTimerInstanceId(), bool delete_on_completion=false)
Definition: timer.cc:201
void ClearState(DBTableBase *tbl_base, ListenerId listener)
Definition: db_entry.cc:73
void Start(Type type, bool associate, AgentRouteWalker::WalkDone walk_done_cb)
WalkDoneCb delete_peer_walker_cb_
Definition: peer.h:219
boost::asio::ip::address_v4 Ip4Address
Definition: address.h:14
bool Cancel()
Definition: timer.cc:150
void AllocDeleteStaleWalker()
Definition: peer.cc:168
VrfTable * vrf_table() const
Definition: agent.h:485
static const uint32_t kDeleteTimeout
Definition: peer.h:124
void ReleaseWalker(AgentRouteWalker *walker)
virtual ~DynamicPeer()
Definition: peer.cc:55
static uint64_t UTCTimestampUsec()
Definition: time_util.h:13
bool Start(int time, Handler handler, ErrorHandler error_handler=NULL)
Definition: timer.cc:108
VrfEntry * vrf() const
Definition: agent_route.h:275
void intrusive_ptr_release(const AsPath *cpath)
Definition: bgp_aspath.h:155
AgentRouteWalkerPtr delete_stale_walker_
Definition: peer.h:216
RouteExport * rt_export_[Agent::ROUTE_TABLE_MAX]
void set_delete_peer_walker_cb(WalkDoneCb cb)
Definition: peer.cc:346
static void ProcessDelete(DynamicPeer *p)
Definition: peer.cc:63
AgentXmppChannel * channel_
Definition: peer.h:210
void ReleasePeerNotifyWalker()
Definition: peer.cc:139
Agent * agent() const
Definition: peer.cc:327
RouteTableType
Definition: agent.h:415
uint32_t refcount() const
Definition: peer.h:93
uint32_t setup_time_
Definition: peer.h:213
Agent * agent() const
ControllerRouteWalker * delete_stale_walker() const
Definition: peer.cc:246
const Ip4Address * router_ip_ptr() const
Definition: agent.h:668
uint64_t sequence_number_
Definition: peer.h:109
static bool ControllerSendSubscribe(AgentXmppChannel *peer, VrfEntry *vrf, bool subscribe)
Type
Definition: peer.h:48
void StopRouteExports()
Definition: peer.h:137
static bool DeleteTimer(Timer *Timer)
Definition: timer.cc:222