OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
mac_learning_mgmt.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017 Juniper Networks, Inc. All rights reserved.
3  */
4 
5 #include <oper/vn.h>
6 #include <oper/vrf.h>
7 #include <oper/nexthop.h>
9 #include <oper/route_common.h>
10 #include "mac_learning_proto.h"
12 #include "mac_learning.h"
13 #include "mac_learning_mgmt.h"
14 #include "mac_ip_learning.h"
15 
17  mac_entry_(ptr), intf_(this), vrf_(this), rt_(this), vn_(this),
18  hc_service_(this) {
19 }
20 
22  MacLearningMgmtDBEntry *entry = vrf_.get();
23  vrf_.reset(NULL);
24  if (entry) {
25  entry->tree()->TryDelete(entry);
26  }
27 
28  entry = intf_.get();
29  intf_.reset(NULL);
30  if (entry) {
31  entry->tree()->TryDelete(entry);
32  }
33 
34  entry = rt_.get();
35  rt_.reset(NULL);
36  if (entry) {
37  entry->tree()->TryDelete(entry);
38  }
39 
40  entry = vn_.get();
41  vn_.reset(NULL);
42  if (entry) {
43  entry->tree()->TryDelete(entry);
44  }
45 
46  entry = hc_service_.get();
47  hc_service_.reset(NULL);
48  if (entry) {
49  entry->tree()->TryDelete(entry);
50  }
51 }
52 
54  vrf_.reset(mgr->Locate(mac_entry_->vrf()));
55 
57  dynamic_cast<MacLearningEntryLocal *>(mac_entry_.get());
58  if (le != NULL) {
59  intf_.reset(mgr->Locate(le->intf()));
60  }
61 
62  MacLearningEntryPBB *pbb_mac =
63  dynamic_cast<MacLearningEntryPBB *>(mac_entry_.get());
64  if (pbb_mac) {
65  rt_.reset(mgr->Locate(pbb_mac->vrf()->bmac_vrf_name(),
66  pbb_mac->bmac()));
67  }
68  MacIpLearningEntry *mac_ip_entry =
69  dynamic_cast<MacIpLearningEntry *>(mac_entry_.get());
70  if (mac_ip_entry != NULL) {
71  intf_.reset(mgr->Locate(mac_ip_entry->intf()));
72  vn_.reset(mgr->Locate(mac_ip_entry->Vn()));
73  hc_service_.reset(mgr->Locate(mac_ip_entry->HcService()));
74  }
75 
76 }
77 
79  type_(type), db_entry_(entry), deleted_(false) {
80 }
81 
83  deleted_ = false;
84  for (MacLearningEntryList::iterator iter = mac_entry_list_.begin();
85  iter != mac_entry_list_.end(); iter++) {
86  MacLearningMgmtNode *ptr = iter.operator->();
89  ptr->mac_learning_entry()));
90 
91  ptr->mac_learning_entry()->EnqueueToTable(req_ptr);
92  }
93 }
94 
95 void MacLearningMgmtDBEntry::Delete(bool set_deleted, bool notify_event) {
96  if (set_deleted) {
97  deleted_ = true;
98  }
99  if (notify_event) {
100  for (MacLearningEntryList::iterator iter = mac_entry_list_.begin();
101  iter != mac_entry_list_.end(); iter++) {
102  MacLearningMgmtNode *ptr = iter.operator->();
105  ptr->mac_learning_entry()));
106  ptr->mac_learning_entry()->EnqueueToTable(req_ptr);
107  }
108  }
109 }
110 
112  if (mac_entry_list_.empty() == false || tree_->Find(this) == NULL) {
113  return false;
114  }
115 
116  if (db_entry_ == NULL || deleted_ == true) {
119  gen_id_));
121  Find(0)->Enqueue(req_ptr);
122  tree_->Erase(this);
123  return true;
124  }
125 
126  return false;
127 }
128 
130  MacLearningMgmtDBEntry(INTERFACE, intf) {
131 }
132 
134  MacLearningMgmtDBEntry(VRF, vrf) {
135 }
136 
138  MacLearningMgmtDBEntry(VN, vn) {
139 }
140 
142  const HealthCheckService *hc) :
143  MacLearningMgmtDBEntry(HC_SERVICE, hc) {
144 }
145 
147  mac_learning_mac_manager_(mgr) {
148 }
149 
151  MacLearningMgmtDBEntry(BRIDGE, rt) {
152  const BridgeRouteEntry *br_rt = dynamic_cast<const BridgeRouteEntry *>(rt);
153  mac_ = br_rt->prefix_address();
154  vrf_ = br_rt->vrf()->GetName();
155 }
156 
159  if (ret == false) {
160  return ret;
161  }
162 
163  //If route entry can be deleted, check if VRF entry can be
164  //deleted
165  VrfKey vrf_key(vrf_);
166  Agent *agent = tree_->mac_learning_mac_manager()->agent();
167  const VrfEntry *vrf = static_cast<const VrfEntry *>(
168  agent->vrf_table()->Find(&vrf_key, true));
169  if (vrf) {
170  MacLearningMgmtVrfEntry mgmt_vrf(vrf);
171  MacLearningMgmtVrfEntry *mgmt_entry =
172  static_cast<MacLearningMgmtVrfEntry *>(
173  tree_->mac_learning_mac_manager()->vrf_tree()->Find(&mgmt_vrf));
174  if (mgmt_entry) {
175  mgmt_entry->tree()->TryDelete(mgmt_entry);
176  }
177  }
178  return ret;
179 }
180 
182  const VrfEntry *vrf = static_cast<const VrfEntry *>(db_entry_);
185  }
186  return false;
187 }
188 
190  const MacAddress &mac):
191  MacLearningMgmtDBEntry(BRIDGE, NULL), vrf_(vrf), mac_(mac) {
192 }
193 
195  tree_.insert(MacLearningMgmtDBPair(entry, entry));
196  entry->set_tree(this);
197 }
198 
200  MacLearningMgmtDBEntry *entry = Find(e);
201  if (entry) {
202  entry->Change();
203  }
204 }
205 
207  MacLearningMgmtDBEntry *entry = Find(e);
208  if (entry) {
209  entry->Delete(true);
210  TryDelete(entry);
211  }
212 }
213 
216  Tree::iterator it = tree_.find(e);
217  if (it == tree_.end()) {
218  return NULL;
219  }
220 
221  return it->second;
222 }
223 
225  tree_.erase(e);
226 }
227 
229  if (e->TryDelete()) {
230  delete e;
231  }
232 }
233 
234 void
236  MacPbbLearningEntry *entry =
237  dynamic_cast<MacPbbLearningEntry *>(ptr->mac_learning_entry().get());
238  MacLearningNodeTree::iterator it =
239  mac_learning_node_tree_.find(entry->key());
240  if (it == mac_learning_node_tree_.end()) {
242  ptr->mac_learning_entry()));
243  node->UpdateRef(this);
244  MacLearningNodePair pair(entry->key(), node);
245  mac_learning_node_tree_.insert(pair);
246  } else {
247  it->second->set_mac_learning_entry(ptr->mac_learning_entry());
248  it->second->UpdateRef(this);
249  }
250 }
251 
252 void
254  MacIpLearningEntry *entry =
255  dynamic_cast<MacIpLearningEntry *>(ptr->mac_learning_entry().get());
256 
257  MacIpLearningNodeTree::iterator it =
258  mac_ip_learning_node_tree_.find(entry->key());
259  if (it == mac_ip_learning_node_tree_.end()) {
261  ptr->mac_learning_entry()));
262  node->UpdateRef(this);
263  MacIpLearningNodePair pair(entry->key(), node);
264  mac_ip_learning_node_tree_.insert(pair);
265  } else {
266  it->second->set_mac_learning_entry(ptr->mac_learning_entry());
267  it->second->UpdateRef(this);
268  }
269 }
270 void
272  MacPbbLearningEntry *entry =
273  dynamic_cast<MacPbbLearningEntry *>(ptr->mac_learning_entry().get());
274  mac_learning_node_tree_.erase(entry->key());
275 }
276 
278  MacIpLearningEntry *entry =
279  dynamic_cast<MacIpLearningEntry *>(ptr->mac_learning_entry().get());
280  mac_ip_learning_node_tree_.erase(entry->key());
281 }
282 
284  MacLearningMgmtDBEntry *entry = Locate(ptr->db_entry());
285  entry->set_db_entry(ptr->db_entry());
286  entry->Change();
287 }
288 
290  bool notify_event) {
291  MacLearningMgmtDBEntry *entry = Find(ptr->db_entry());
292  if (entry) {
293  entry->Delete(true, notify_event);
294  entry->set_gen_id(ptr->gen_id());
295  entry->tree()->TryDelete(entry);
296  }
297 }
298 
300  MacLearningMgmtDBEntry *entry = Find(ptr->db_entry());
301  if (entry) {
302  entry->Delete(false);
303  }
304 }
305 
306 bool
308  switch(ptr->event()) {
311  AddMacLearningEntry(ptr);
312  break;
313 
316  break;
317 
320  AddDBEntry(ptr);
321  break;
322 
324  DeleteDBEntry(ptr);
325  break;
326 
328  DeleteDBEntry(ptr, false);
329  break;
331  DeleteAllEntry(ptr);
332  break;
333 
337  break;
338 
341  break;
342  default:
343  assert(0);
344  }
345 
346  return true;
347 }
348 
350  request_queue_.Enqueue(ptr);
351 }
352 
354 MacLearningMgmtManager::Locate(const std::string &vrf, const MacAddress &mac) {
355  MacLearningMgmtRouteEntry mgmt_rt(vrf, mac);
356  MacLearningMgmtRouteEntry *mgmt_entry =
357  static_cast<MacLearningMgmtRouteEntry *>(rt_tree_.Find(&mgmt_rt));
358  if (mgmt_entry != NULL) {
359  return mgmt_entry;
360  }
361 
362  mgmt_entry = new MacLearningMgmtRouteEntry(vrf, mac);
363  rt_tree_.Add(mgmt_entry);
364  return mgmt_entry;
365 }
366 
367 bool MacLearningMgmtManager::IsVrfRouteEmpty(const std::string &vrf_name) {
368 
369  MacLearningMgmtRouteEntry rt_entry(vrf_name, MacAddress::ZeroMac());
370  MacLearningMgmtRouteEntry *rt_entry_ptr =
371  static_cast<MacLearningMgmtRouteEntry *>(rt_tree_.LowerBound(&rt_entry));
372  if (rt_entry_ptr && rt_entry_ptr->vrf() == vrf_name) {
373  return false;
374  }
375 
376  return true;
377 }
378 
381  if (e == NULL) {
382  return NULL;
383  }
384 
385  MacLearningMgmtDBEntry *mgmt_entry = NULL;
386  const Interface *intf = dynamic_cast<const Interface *>(e);
387  if (intf != NULL) {
388  MacLearningMgmtIntfEntry mgmt_intf(intf);
389  mgmt_entry = intf_tree_.Find(&mgmt_intf);
390  return mgmt_entry;
391  }
392 
393  const VrfEntry *vrf = dynamic_cast<const VrfEntry *>(e);
394  if (vrf != NULL) {
395  MacLearningMgmtVrfEntry mgmt_vrf(vrf);
396  mgmt_entry = vrf_tree_.Find(&mgmt_vrf);
397  return mgmt_entry;
398  }
399 
400  const AgentRoute *rt = dynamic_cast<const AgentRoute *>(e);
401  if (rt != NULL) {
402  MacLearningMgmtRouteEntry mgmt_rt(rt);
403  mgmt_entry = rt_tree_.Find(&mgmt_rt);
404  return mgmt_entry;
405  }
406 
407  const VnEntry *vn = dynamic_cast<const VnEntry *>(e);
408  if (vn != NULL) {
409  MacLearningMgmtVnEntry mgmt_vn(vn);
410  mgmt_entry = vn_tree_.Find(&mgmt_vn);
411  return mgmt_entry;
412  }
413 
414  const HealthCheckService *hc = dynamic_cast<const HealthCheckService *>(e);
415  if (hc != NULL) {
416  MacLearningMgmtHcServiceEntry mgmt_hc(hc);
417  mgmt_entry = hc_tree_.Find(&mgmt_hc);
418  return mgmt_entry;
419  }
420  return NULL;
421 }
422 
423 
426  if (e == NULL) {
427  return NULL;
428  }
429 
430  MacLearningMgmtDBEntry *mgmt_entry = NULL;
431  const Interface *intf = dynamic_cast<const Interface *>(e);
432  if (intf != NULL) {
433  MacLearningMgmtIntfEntry mgmt_intf(intf);
434  mgmt_entry = intf_tree_.Find(&mgmt_intf);
435  if (mgmt_entry != NULL) {
436  return mgmt_entry;
437  }
438 
439  mgmt_entry = new MacLearningMgmtIntfEntry(intf);
440  intf_tree_.Add(mgmt_entry);
441  return mgmt_entry;
442  }
443 
444  const VrfEntry *vrf = dynamic_cast<const VrfEntry *>(e);
445  if (vrf != NULL) {
446  MacLearningMgmtVrfEntry mgmt_vrf(vrf);
447  mgmt_entry = vrf_tree_.Find(&mgmt_vrf);
448  if (mgmt_entry != NULL) {
449  return mgmt_entry;
450  }
451 
452  mgmt_entry = new MacLearningMgmtVrfEntry(vrf);
453  vrf_tree_.Add(mgmt_entry);
454  return mgmt_entry;
455  }
456 
457  const AgentRoute *rt = dynamic_cast<const AgentRoute *>(e);
458  if (rt != NULL) {
459  MacLearningMgmtRouteEntry mgmt_rt(rt);
460  mgmt_entry = rt_tree_.Find(&mgmt_rt);
461  if (mgmt_entry != NULL) {
462  return mgmt_entry;
463  }
464 
465  mgmt_entry = new MacLearningMgmtRouteEntry(rt);
466  rt_tree_.Add(mgmt_entry);
467  return mgmt_entry;
468  }
469  const VnEntry *vn = dynamic_cast<const VnEntry *>(e);
470  if (vn != NULL) {
471  MacLearningMgmtVnEntry mgmt_vn(vn);
472  mgmt_entry = vn_tree_.Find(&mgmt_vn);
473  if (mgmt_entry != NULL) {
474  return mgmt_entry;
475  }
476  mgmt_entry = new MacLearningMgmtVnEntry(vn);
477  vn_tree_.Add(mgmt_entry);
478  return mgmt_entry;
479  }
480  const HealthCheckService *hc = dynamic_cast<const HealthCheckService *>(e);
481  if (hc != NULL) {
482  MacLearningMgmtHcServiceEntry mgmt_hc(hc);
483  mgmt_entry = hc_tree_.Find(&mgmt_hc);
484  if (mgmt_entry != NULL) {
485  return mgmt_entry;
486  }
487  mgmt_entry = new MacLearningMgmtHcServiceEntry(hc);
488  hc_tree_.Add(mgmt_entry);
489  return mgmt_entry;
490 
491  }
492  return NULL;
493 }
494 
496  agent_(agent), intf_tree_(this), vrf_tree_(this), rt_tree_(this),
497  vn_tree_(NULL), hc_tree_(NULL),
498  request_queue_(agent_->task_scheduler()->GetTaskId(kTaskMacLearningMgmt), 0,
499  boost::bind(&MacLearningMgmtManager::RequestHandler,
500  this, _1)) {
501 }
void Enqueue(MacLearningMgmtRequestPtr &ptr)
void DeleteAllEntry(MacLearningMgmtRequestPtr ptr)
static const MacAddress & ZeroMac()
Definition: mac_address.h:158
DependencyRef< MacLearningMgmtNode, MacLearningMgmtDBEntry > intf_
MacLearningEntryPtr mac_learning_entry()
MacLearningEntryPtr mac_entry_
void Delete(MacLearningMgmtDBEntry *entry)
void Change(MacLearningMgmtDBEntry *entry)
static Agent * GetInstance()
Definition: agent.h:436
MacLearningMgmtManager(Agent *agent)
Definition: vrf.h:86
MacLearningMgmtDBTree hc_tree_
MacLearningMgmtDBEntry * Find(const DBEntry *e)
boost::shared_ptr< MacLearningMgmtRequest > MacLearningMgmtRequestPtr
const MacLearningKey & key() const
Definition: mac_learning.h:104
MacLearningProto * mac_learning_proto() const
Definition: agent.h:1005
DependencyRef< MacLearningMgmtNode, MacLearningMgmtDBEntry > rt_
void DeleteMacLearningEntry(MacLearningMgmtRequestPtr ptr)
const HealthCheckService * HcService()
const Interface * intf()
void set_tree(MacLearningMgmtDBTree *tree)
MacLearningMgmtQueue request_queue_
MacLearningMgmtDBTree intf_tree_
ObjectType * get() const
Definition: dependency.h:49
void UpdateRef(MacLearningMgmtManager *mgr)
const string & GetName() const
Definition: vrf.h:100
Base class for all Route entries in agent.
Definition: agent_route.h:224
MacLearningMgmtHcServiceEntry(const HealthCheckService *hc)
MacLearningMgmtDBTree * tree() const
void AddMacLearningEntry(MacLearningMgmtRequestPtr ptr)
MacLearningMgmtDBTree(MacLearningMgmtManager *mgr)
MacLearningMgmtDBTree vn_tree_
#define kTaskMacLearningMgmt
Definition: agent.h:342
MacLearningMgmtDBTree vrf_tree_
MacLearningMgmtRouteEntry(const AgentRoute *rt)
void set_gen_id(uint32_t gen_id)
uint8_t type
Definition: load_balance.h:109
Definition: agent.h:358
DependencyRef< MacLearningMgmtNode, MacLearningMgmtDBEntry > hc_service_
std::pair< MacLearningKey, MacLearningMgmtNodePtr > MacLearningNodePair
Definition: vrf.h:22
void Delete(bool set_delete, bool notify_event=true)
MacLearningMgmtNode(MacLearningEntryPtr ptr)
MacLearningMgmtVrfEntry(const VrfEntry *vrf)
void DeleteDBEntry(MacLearningMgmtRequestPtr ptr, bool notify_event=true)
void TryDelete(MacLearningMgmtDBEntry *db_entry)
std::pair< MacLearningMgmtDBEntry *, MacLearningMgmtDBEntry * > MacLearningMgmtDBPair
MacLearningMgmtManager * mac_learning_mac_manager()
bool Enqueue(PktInfoPtr msg)
void AddMacIpLearningEntry(MacLearningMgmtRequestPtr ptr)
MacLearningMgmtDBTree * vrf_tree()
boost::shared_ptr< MacLearningEntryRequest > MacLearningEntryRequestPtr
void set_db_entry(const DBEntry *entry)
AgentDBEntry * Find(const DBEntry *key, bool ret_del)
Definition: agent_db.cc:134
MacLearningMgmtIntfEntry(const Interface *intf)
void DeleteMacIpLearningEntry(MacLearningMgmtRequestPtr ptr)
std::pair< MacIpLearningKey, MacLearningMgmtNodePtr > MacIpLearningNodePair
virtual const PrefixType & prefix_address() const
Returns the value of a stored prefix address (IPv4, IPv6 or MAC address)
Definition: agent_route.h:375
void Erase(MacLearningMgmtDBEntry *entry)
Definition: vn.h:151
VrfTable * vrf_table() const
Definition: agent.h:485
MacLearningMgmtDBEntry * Find(MacLearningMgmtDBEntry *entry)
DependencyRef< MacLearningMgmtNode, MacLearningMgmtDBEntry > vrf_
const VnEntry * Vn()
DependencyRef< MacLearningMgmtNode, MacLearningMgmtDBEntry > vn_
const Interface * intf()
Definition: mac_learning.h:154
const MacIpLearningKey & key() const
MacLearningMgmtDBTree * tree_
void Add(MacLearningMgmtDBEntry *entry)
VrfEntry * vrf() const
Definition: agent_route.h:275
MacLearningMgmtVnEntry(const VnEntry *vn)
MacLearningMgmtDBTree rt_tree_
MacLearningMgmtDBEntry(Type type_, const DBEntry *entry)
boost::shared_ptr< MacLearningMgmtNode > MacLearningMgmtNodePtr
bool IsVrfRouteEmpty(const std::string &vrf_name)
MacLearningMgmtDBEntry * Locate(const DBEntry *e)
void AddDBEntry(MacLearningMgmtRequestPtr ptr)
const std::string & vrf()
void reset(ObjectType *ptr)
Definition: dependency.h:32
MacLearningMgmtDBEntry * LowerBound(MacLearningMgmtDBEntry *entry)
VrfEntry * vrf() const
MacLearningNodeTree mac_learning_node_tree_
bool Enqueue(QueueEntryT entry)
Definition: queue_task.h:248
bool RequestHandler(MacLearningMgmtRequestPtr ptr)
MacIpLearningNodeTree mac_ip_learning_node_tree_
const MacAddress & bmac() const
Definition: mac_learning.h:193
const std::string bmac_vrf_name() const
Definition: vrf.h:201
boost::shared_ptr< MacLearningEntry > MacLearningEntryPtr