OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
mac_learning.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017 Juniper Networks, Inc. All rights reserved.
3  */
4 #include <init/agent_param.h>
5 #include <oper/vn.h>
6 #include <oper/sg.h>
7 #include <oper/vrf.h>
8 #include <oper/nexthop.h>
10 #include <oper/route_common.h>
11 #include "mac_learning_proto.h"
13 #include "mac_learning_init.h"
14 #include "mac_learning.h"
15 #include "mac_learning_mgmt.h"
16 #include "mac_aging.h"
17 #include "vr_bridge.h"
18 
19 
21  const MacAddress &mac,
22  uint32_t index):
23  MacLearningEntry(vrf_id),mac_learning_table_(table), key_(vrf_id, mac), index_(index) {
24  vrf_ = table->agent()->vrf_table()->
25  FindVrfFromIdIncludingDeletedVrf(key_.vrf_id_);
26 }
27 
29  deleted_ = true;
32 
35  vrf()->GetName(), mac(), Ip4Address(0), 32, 0, NULL);
36 }
37 
39  if (Add()) {
42  }
43 }
44 
46  if (Add()) {
49  }
50 }
51 
54 }
56  uint32_t vrf_id,
57  const MacAddress &mac,
58  uint32_t index,
59  InterfaceConstRef intf):
60  MacPbbLearningEntry(table, vrf_id, mac, index), intf_(intf) {
61 }
62 
64  const VmInterface *vm_intf = dynamic_cast<const VmInterface *>(intf_.get());
65  assert(vm_intf);
66 
67  if (vrf()->IsActive() == false) {
68  return false;
69  }
70 
71  if (vm_intf->vn() == NULL) {
72  return false;
73  }
74 
75  if (vm_intf->vn() == NULL) {
76  return false;
77  }
78 
79  SecurityGroupList sg_list;
80  vm_intf->CopySgIdList(&sg_list);
81 
82  TagList tag_list;
83  vm_intf->CopyTagIdList(&tag_list);
84 
86  AddLocalVmRouteReq(mac_learning_table_->agent()->mac_learning_peer(),
87  vrf()->GetName(),
88  mac(), vm_intf, Ip4Address(0),
89  vm_intf->l2_label(),
90  vm_intf->vn()->GetName(), sg_list, tag_list,
91  PathPreference(), 0,
92  vm_intf->etree_leaf());
93  return true;
94 }
95 
97  uint32_t vrf_id,
98  const MacAddress &mac,
99  uint32_t index,
100  IpAddress remote_ip):
101  MacPbbLearningEntry(table, vrf_id, mac, index), remote_ip_(remote_ip) {
102 }
103 
105  return true;
106 }
107 
109  uint32_t vrf_id,
110  const MacAddress &mac,
111  uint32_t index,
112  const MacAddress &bmac) :
113  MacPbbLearningEntry(table, vrf_id, mac, index), bmac_(bmac) {
114 }
115 
117  assert(vrf_);
118  uint32_t isid = vrf_->isid();
119  std::string bmac_vrf_name = vrf_->bmac_vrf_name();
120  PBBRoute *data = new PBBRoute(VrfKey(bmac_vrf_name), bmac_, isid,
121  VnListType(),
124  mac_learning_peer(),
125  vrf()->GetName(),
126  mac(), Ip4Address(0), 32, 0, data);
127  return true;
128 }
129 
131  TokenPool *pool):
132  partition_(partition), pool_(pool),
133  queue_(partition_->agent()->task_scheduler()->GetTaskId(kTaskMacLearning),
134  partition->id(),
135  boost::bind(&MacLearningRequestQueue::HandleEvent, this, _1)) {
137  this));
138 }
139 
141  if (pool_) {
142  return pool_->TokenCheck();
143  }
144 
145  return true;
146 }
147 
149  return partition_->RequestHandler(ptr);
150 }
151 
153  MacLearningProto *proto,
154  uint32_t id):
155  agent_(agent), id_(id),
156  add_request_queue_(this, proto->add_tokens()),
157  change_request_queue_(this, proto->change_tokens()),
158  delete_request_queue_(this, proto->delete_tokens()) {
159  aging_partition_.reset(new MacAgingPartition(agent, id));
160 }
161 
163  assert(mac_learning_table_.size() == 0);
164 }
165 
167  if (agent_->mac_learning_proto()->add_tokens() == pool) {
169  } else if (agent_->mac_learning_proto()->change_tokens() == pool) {
171  } else {
173  }
174 }
175 
177  switch(ptr->event()) {
179  agent()->mac_learning_proto()->ProcessProto(ptr->pkt_info());
180  break;
181 
183  Add(ptr->mac_learning_entry());
184  break;
185 
187  Resync(ptr->mac_learning_entry());
188  break;
189 
191  Delete(ptr->mac_learning_entry());
192  break;
193 
196  mac_learning_db_client()->FreeDBState(ptr->db_entry(),
197  ptr->gen_id());
198  break;
199 
200  default:
201  assert(0);
202  }
203  return true;
204 }
205 
208  if (add == false) {
210  }
213 }
214 
216  MacPbbLearningEntry *entry = dynamic_cast<MacPbbLearningEntry *>(ptr.get());
217  if (!entry) {
218  return;
219  }
220  MacLearningKey key(ptr->vrf_id(), entry->mac());
221 
222  std::pair<MacLearningEntryTable::iterator, bool> it =
223  mac_learning_table_.insert(MacLearningEntryPair(key, ptr));
224  if (it.second == false) {
225  //Entry already present, clear the entry and delete it from
226  //aging tree
227  ptr->CopyToken(it.first->second.get());
228  if (it.first->second->deleted() == false) {
230  MacLearningEntryRequest::DELETE_MAC, it.first->second));
231  aging_partition_->Enqueue(aging_req);
232  }
233  mac_learning_table_[key] = ptr;
234  }
235 
236  ptr->AddWithToken();
237  EnqueueMgmtReq(ptr, true);
240  aging_partition_->Enqueue(aging_req);
241 }
242 
244  if (ptr->deleted() == true) {
245  return;
246  }
247  MacPbbLearningEntry *entry = dynamic_cast<MacPbbLearningEntry *>(ptr.get());
248  if (!entry) {
249  return;
250  }
251  MacLearningKey key(ptr->vrf_id(), entry->mac());
252  if (mac_learning_table_.find(key) == mac_learning_table_.end()) {
253  return;
254  }
255 
256  ptr->Delete();
259  ptr));
260  aging_partition_->Enqueue(aging_req);
261  EnqueueMgmtReq(ptr, false);
262 }
263 
265  MacPbbLearningEntry *entry = dynamic_cast<MacPbbLearningEntry *>(ptr.get());
266  if (!entry) {
267  return;
268  }
269  MacLearningKey key(ptr->vrf_id(), entry->mac());
270  if (mac_learning_table_.find(key) == mac_learning_table_.end()) {
271  return;
272  }
273 
274  ptr->Resync();
275 }
276 
278  switch(req->event()) {
284  break;
285 
288  break;
289 
292  break;
293 
294  default:
295  assert(0);
296  }
297  return;
298 }
299 
302  MacLearningEntryTable::iterator it = mac_learning_table_.find(key);
303  if (it == mac_learning_table_.end()) {
304  return NULL;
305  }
306  return it->second.get();
307 }
308 
311  MacLearningEntryTable::iterator it = mac_learning_table_.find(key);
312  return it->second;
313 }
314 
316  MacLearningEntry *mac_entry = Find(key);
317  if (mac_entry) {
318  mac_entry->ReleaseToken();
319  if (mac_entry->deleted()) {
320  mac_learning_table_.erase(key);
321  }
322  }
323 }
324 
326  MacEntryResp *resp,
327  std::string resp_ctx,
328  std::string key,
329  const MacAddress &mac) :
330  Task((TaskScheduler::GetInstance()->
331  GetTaskId("Agent::MacLearningSandeshTask")), 0),
332  agent_(agent), resp_(resp), resp_data_(resp_ctx), partition_id_(0),
333  vrf_id_(0), mac_(MacAddress::ZeroMac()), exact_match_(false),
334  user_given_mac_(mac) {
335  if (key != agent_->NullString()) {
336  SetMacKey(key);
337  }
338 }
339 
341 }
342 
344  const char ch = kDelimiter;
345  size_t n = std::count(key.begin(), key.end(), ch);
346  if (n != 3) {
347  return false;
348  }
349 
350  std::stringstream ss(key);
351  string item;
352 
353  if (getline(ss, item, ch)) {
354  std::istringstream(item) >> partition_id_;
355  }
356  if (getline(ss, item, ch)) {
357  std::istringstream(item) >> vrf_id_;
358  }
359  if (getline(ss, item, ch)) {
361  }
362  if (getline(ss, item, ch)) {
363  std::istringstream(item) >> exact_match_;
364  }
365  return true;
366 }
367 
368 string
370  std::stringstream ss;
371  ss << partition_id_ << kDelimiter;
372  ss << vrf_id_ << kDelimiter;
373  ss << mac_.ToString();
374  ss << kDelimiter << exact_match_;
375  return ss.str();
376 }
377 
381  return NULL;
382  }
383 
385  Find(partition_id_);
386  return mp;
387 }
388 
389 bool
391  std::vector<SandeshMacEntry>& list =
392  const_cast<std::vector<SandeshMacEntry>&>(resp_->get_mac_entry_list());
393  uint32_t entries_count = 0;
394 
395  while (entries_count < kMaxResponse) {
396  const MacLearningPartition *mp = GetPartition();
397  if (mp == NULL) {
398  break;
399  }
400 
402  MacLearningPartition::MacLearningEntryTable::const_iterator it;
404  it = mp->mac_learning_table_.find(key);
405  } else {
406  it = mp->mac_learning_table_.upper_bound(key);
407  }
408 
409  while (entries_count < kMaxResponse) {
410  if (exact_match_ && it->first.vrf_id_ != vrf_id_) {
411  break;
412  } else {
413  vrf_id_ = it->first.vrf_id_;
414  }
415 
416  if (it == mp->mac_learning_table_.end()) {
417  break;
418  }
419 
420  const MacAgingTable *at =
421  mp->aging_partition()->Find(it->first.vrf_id_);
422  //Find the aging entry
423  const MacAgingEntry *aging_entry = NULL;
424  if (at) {
425  aging_entry = at->Find(it->second.get());
426  }
427  if (aging_entry) {
428  SandeshMacEntry data;
429  data.set_partition(partition_id_);
430  aging_entry->FillSandesh(&data);
431  list.push_back(data);
432  }
433 
434  entries_count++;
436  break;
437  }
438  mac_ = it->first.mac_;
439  it++;
440  }
441 
442  if (entries_count >= kMaxResponse) {
443  break;
444  }
445 
446  if (exact_match_ == false) {
447  vrf_id_++;
448  }
449 
450  if (it == mp->mac_learning_table_.end()) {
451  partition_id_++;
452  if (exact_match_ == false) {
453  vrf_id_ = 0;
454  }
455  }
456 
458  //If entry is found in current partition
459  //move on to next partition
460  if (it != mp->mac_learning_table_.end()) {
461  partition_id_++;
462  }
464  } else {
466  }
467  }
468 
469  if (partition_id_ < agent_->params()->mac_learning_thread_count()) {
470  resp_->set_mac_key(GetMacKey());
471  }
472 
474  return true;
475 }
476 
478  resp->set_context(resp_data_);
479  resp->set_more(false);
480  resp->Response();
481 }
482 
483 void FetchMacEntry::HandleRequest() const {
484  Agent *agent = Agent::GetInstance();
485 
486  std::ostringstream str;
487  str << "0" << MacLearningSandeshResp::kDelimiter << get_vrf_id() <<
489 
490  bool exact_match = false;
491  if (get_vrf_id() != 0 || get_mac() != agent->NullString()) {
492  exact_match = true;
493  }
494  str << MacLearningSandeshResp::kDelimiter << exact_match;
495 
496  MacAddress mac = MacAddress::FromString(get_mac());
497 
498  MacEntryResp *resp = new MacEntryResp();
500  context(),
501  str.str(), mac);
503  scheduler->Enqueue(task);
504 }
505 
506 void NextMacEntrySet::HandleRequest() const {
507  Agent *agent = Agent::GetInstance();
508 
509  MacEntryResp *resp = new MacEntryResp();
510  MacLearningSandeshResp *task = new MacLearningSandeshResp(agent, resp,
511  context(),
512  get_mac_entry_key(),
515  scheduler->Enqueue(task);
516 }
virtual ~MacLearningPartition()
void Enqueue(MacLearningMgmtRequestPtr &ptr)
static const MacAddress & ZeroMac()
Definition: mac_address.h:158
void Add(MacLearningEntryPtr ptr)
MacLearningEntryRemote(MacLearningPartition *table, uint32_t vrf_id, const MacAddress &mac, uint32_t index, const IpAddress remote_ip)
Definition: mac_learning.cc:96
MacEntryResp * resp_
Definition: mac_learning.h:279
void AddToken(TokenPtr ptr)
Definition: mac_learning.h:108
const MacAddress & mac() const
Definition: mac_learning.h:96
static Agent * GetInstance()
Definition: agent.h:436
The TaskScheduler keeps track of what tasks are currently schedulable. When a task is enqueued it is ...
Definition: task.h:178
bool etree_leaf() const
MacAgingPartition * aging_partition() const
Definition: mac_learning.h:231
boost::shared_ptr< MacLearningMgmtRequest > MacLearningMgmtRequestPtr
MacLearningRequestQueue change_request_queue_
Definition: mac_learning.h:253
const MacAddress bmac_
Definition: mac_learning.h:198
virtual ~MacLearningSandeshResp()
TokenPool * add_tokens()
MacLearningPartition * partition_
boost::asio::ip::address IpAddress
Definition: address.h:13
MacLearningProto * mac_learning_proto() const
Definition: agent.h:1005
MacAddress user_given_mac_
Definition: mac_learning.h:285
virtual bool TokenCheck()
std::string GetMacKey()
const Peer * mac_learning_peer() const
Definition: agent.h:1036
MacLearningRequestQueue delete_request_queue_
Definition: mac_learning.h:254
std::vector< int > SecurityGroupList
Definition: agent.h:201
void EnqueueMgmtReq(MacLearningEntryPtr ptr, bool add)
boost::shared_ptr< MacAgingPartition > aging_partition_
Definition: mac_learning.h:255
MacLearningModule * mac_learning_module() const
Definition: agent.h:1013
MacAgingTable * Find(uint32_t id)
Definition: mac_aging.h:124
Definition: task_int.h:10
const string & GetName() const
Definition: vrf.h:100
virtual void AddWithToken()
Definition: mac_learning.cc:38
MacLearningRequestQueue(MacLearningPartition *partition, TokenPool *pool)
bool RequestHandler(MacLearningEntryRequestPtr ptr)
std::string ToString() const
Definition: mac_address.cc:53
const MacAgingEntry * Find(MacLearningEntry *me) const
Definition: mac_aging.h:81
virtual void Response()
Definition: p/sandesh.h:502
const MacLearningPartition * GetPartition()
virtual void Resync()
Definition: mac_learning.cc:45
Definition: agent.h:358
MacLearningSandeshResp(Agent *agent, MacEntryResp *resp, std::string resp_ctx, std::string key, const MacAddress &mac)
MacLearningPartition * mac_learning_table_
Definition: mac_learning.h:134
void MayBeStartRunner(TokenPool *pool)
virtual bool HandleEvent(MacLearningEntryRequestPtr ptr)
static TaskScheduler * GetInstance()
Definition: task.cc:547
void Enqueue(Task *task)
Enqueues a task for running. Starts task if all policy rules are met else puts task in waitq...
Definition: task.cc:636
Definition: vrf.h:22
MacLearningEntryPBB(MacLearningPartition *table, uint32_t vrf_id, const MacAddress &mac, uint32_t index, const MacAddress &bmac)
bool Run()
Code to execute. Returns true if task is completed. Return false to reschedule the task...
bool SetMacKey(string key)
MacLearningKey key_
Definition: mac_learning.h:135
static const std::string & NullString()
Definition: agent.h:437
std::pair< MacLearningKey, MacLearningEntryPtr > MacLearningEntryPair
Definition: mac_learning.h:209
boost::intrusive_ptr< const Interface > InterfaceConstRef
Definition: agent.h:51
boost::shared_ptr< MacLearningEntryRequest > MacLearningEntryRequestPtr
const VnEntry * vn() const
AgentParam * params() const
Definition: agent.h:1218
std::set< std::string > VnListType
Definition: agent.h:212
bool deleted() const
void ReleaseToken(const MacLearningKey &key)
static const char kDelimiter
Definition: mac_learning.h:262
boost::asio::ip::address_v4 Ip4Address
Definition: address.h:14
MacLearningPartition(Agent *agent, MacLearningProto *proto, uint32_t id)
VrfTable * vrf_table() const
Definition: agent.h:485
void Enqueue(MacLearningEntryRequestPtr ptr)
MacPbbLearningEntry(MacLearningPartition *table, uint32_t vrf_id, const MacAddress &mac, uint32_t index)
Definition: mac_learning.cc:20
virtual void Delete()
Definition: mac_learning.cc:28
virtual void ReleaseToken()
MacLearningEntryLocal(MacLearningPartition *table, uint32_t vrf_id, const MacAddress &mac, uint32_t index, InterfaceConstRef intf)
Definition: mac_learning.cc:55
void set_context(std::string context)
Definition: p/sandesh.h:310
void Delete(MacLearningEntryPtr ptr)
void EnqueueToTable(MacLearningEntryRequestPtr req)
Definition: mac_learning.cc:52
uint32_t l2_label() const
Definition: interface.h:128
void SendResponse(SandeshResponse *resp)
void FillSandesh(SandeshMacEntry *sme) const
Definition: mac_aging.cc:27
virtual bool Add()=0
void Resync(MacLearningEntryPtr ptr)
const uint32_t vrf_id_
uint32_t mac_learning_thread_count() const
Definition: agent_param.h:534
const string & GetName() const
Definition: vn.h:162
void SetStartRunnerFunc(StartRunnerFunc start_runner_fn)
Definition: queue_task.h:192
static const uint32_t kMaxResponse
Definition: mac_learning.h:261
MacLearningEntryTable mac_learning_table_
Definition: mac_learning.h:251
VrfEntry * vrf() const
EvpnAgentRouteTable * fabric_evpn_table() const
Definition: agent.h:611
MacLearningRequestQueue add_request_queue_
Definition: mac_learning.h:252
static MacAddress FromString(const std::string &str, boost::system::error_code *error=NULL)
Definition: mac_address.cc:71
TokenPool * change_tokens()
bool ProcessProto(boost::shared_ptr< PktInfo > msg_info)
Task is a wrapper over tbb::task to support policies.
Definition: task.h:86
void CopySgIdList(SecurityGroupList *sg_id_list) const
void Enqueue(MacLearningEntryRequestPtr req)
MacLearningMgmtManager * mac_learning_mgmt() const
virtual void set_more(const bool val)=0
#define kTaskMacLearning
Definition: agent.h:341
bool TokenCheck() const
Definition: flow_token.cc:32
MacLearningEntry * Find(const MacLearningKey &key)
boost::shared_ptr< MacLearningEntry > MacLearningEntryPtr
std::vector< int > TagList
Definition: agent.h:202
InterfaceConstRef intf_
Definition: mac_learning.h:159
MacLearningEntryPtr TestGet(const MacLearningKey &key)
void CopyTagIdList(TagList *tag_id_list) const
static void AddRemoteVmRouteReq(const Peer *peer, const std::string &vrf_name, const MacAddress &mac, const IpAddress &ip_addr, uint32_t plen, uint32_t ethernet_tag, AgentRouteData *data)