OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
mac_aging.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017 Juniper Networks, Inc. All rights reserved.
3  */
4 #include <oper/vn.h>
5 #include <oper/sg.h>
6 #include <oper/vm.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_aging.h"
16 #include "mac_learning_mgmt.h"
17 #include "vr_bridge.h"
20 
22  mac_learning_entry_(ptr), packets_(0), deleted_(false) {
25 }
26 
27 void MacAgingEntry::FillSandesh(SandeshMacEntry *smac) const {
28  MacPbbLearningEntry *entry =
29  dynamic_cast<MacPbbLearningEntry *>(mac_learning_entry_.get());
30  smac->set_vrf(mac_learning_entry_->vrf()->GetName());
31  smac->set_mac(entry->mac().ToString());
32  smac->set_index(entry->index());
33  smac->set_packets(packets_);
34  std::string time_since_addition =
36  smac->set_time_since_add(time_since_addition);
37  std::string last_stats_change =
39  smac->set_last_stats_change(last_stats_change);
40 }
41 
43  agent_(agent), timeout_msec_(kDefaultAgingTimeout), vrf_(vrf) {
44 }
45 
47 }
48 
50  MacAgingEntryTable::iterator it = aging_table_.find(ptr.get());
51  if (it != aging_table_.end()) {
52  it->second->set_deleted(false);
53  return;
54  }
55 
56  MacAgingEntryPtr aging_entry_ptr(new MacAgingEntry(ptr));
57  aging_table_.insert(MacAgingPair(ptr.get(), aging_entry_ptr));
58  Trace("Adding MAC entry", aging_entry_ptr.get());
59 }
60 
62  MacAgingEntryTable::iterator it = aging_table_.find(ptr.get());
63  if (it != aging_table_.end()) {
64  Trace("Deleting MAC entry", it->second.get());
65  aging_table_.erase(it);
66  }
67 }
68 
70  MacPbbLearningEntry *entry =
71  dynamic_cast<MacPbbLearningEntry *>(ptr->mac_learning_entry().get());
72  uint32_t index = entry->index();
73  vr_bridge_entry *vr_entry = agent_->ksync()->ksync_bridge_memory()->
74  GetBridgeEntry(index);
75  if (vr_entry == NULL) {
76  ptr->set_packets(0);
77  } else {
78  ptr->set_packets(vr_entry->be_packets);
79  }
80 }
81 
82 
84  uint64_t curr_time) {
85  uint64_t packets = ptr->packets();
86 
87  ReadStats(ptr);
88 
89  if (packets == ptr->packets()) {
90  if (curr_time - ptr->last_modified_time() > timeout_in_usecs()) {
91  return true;
92  }
93  return false;
94  }
95 
96  ptr->set_last_modified_time(curr_time);
97  return false;
98 }
99 
100 void MacAgingTable::Trace(const std::string &str, MacAgingEntry *ptr) {
101  std::string vrf = "";
102  if (ptr->mac_learning_entry()->vrf() != NULL) {
103  vrf = ptr->mac_learning_entry()->vrf()->GetName();
104  }
105  MacPbbLearningEntry *entry =
106  dynamic_cast<MacPbbLearningEntry *>(ptr->mac_learning_entry().get());
107  MAC_AGING_TRACE(MacLearningTraceBuf, vrf,
108  entry->mac().ToString(),
109  entry->index(),
110  ptr->packets(), str);
111 }
112 
114  Trace("Aging", ptr);
115  ptr->set_deleted(true);
118  ptr->mac_learning_entry()->EnqueueToTable(req);
119 }
120 
121 uint32_t
122 MacAgingTable::CalculateEntriesPerIteration(uint32_t aging_table_entry_count) {
123  uint32_t entry_count = aging_table_entry_count;
124 
125  if (vrf_) {
126  timeout_msec_ = vrf_->mac_aging_time() * 1000;
127  }
128 
129  if (timeout_msec_ == 0) {
130  return 0;
131  }
132 
133  //We want to scan all the entries 2 times before aging timeout
134  uint32_t table_scan_time = timeout_msec_ / 10;
135 
136  uint32_t no_of_iteration = table_scan_time /
138 
139  if (no_of_iteration == 0) {
140  no_of_iteration = 1;
141  }
142 
143  uint32_t entry_count_per_iteration = entry_count / no_of_iteration;
144 
145  if (entry_count_per_iteration < kMinEntriesPerScan) {
146  entry_count_per_iteration = kMinEntriesPerScan;
147  }
148  return entry_count_per_iteration;
149 }
150 
152  uint64_t curr_time = UTCTimestampUsec();
153 
154  MacAgingEntryTable::const_iterator it = aging_table_.upper_bound(last_key_);
155  if (it == aging_table_.end()) {
156  it = aging_table_.begin();
157  }
158 
159  uint32_t i = 0;
160  uint32_t entries = CalculateEntriesPerIteration(aging_table_.size());
161  while (it != aging_table_.end() && i < entries) {
162  if (it->second->deleted() == false &&
163  ShouldBeAged(it->second.get(), curr_time)) {
164  SendDeleteMsg(it->second.get());
165  }
166  last_key_ = it->first;
167  it++;
168  i++;
169  }
170 
171  if (aging_table_.size() == 0) {
172  return false;
173  }
174 
175  return true;
176 }
177 
178 MacAgingPartition::MacAgingPartition(Agent *agent, uint32_t partition_id) :
179  agent_(agent), partition_id_(partition_id),
180  request_queue_(agent_->task_scheduler()->GetTaskId(kTaskMacAging),
181  partition_id,
182  boost::bind(&MacAgingPartition::RequestHandler,
183  this, _1)),
184  timer_(TimerManager::CreateTimer(*(agent->event_manager()->io_service()),
185  "MacAgingTimer",
186  agent->task_scheduler()->
187  GetTaskId(kTaskMacAging), partition_id)) {
188 }
189 
192 }
193 
195  request_queue_.Enqueue(req);
196 }
197 
199  uint32_t vrf_id = mle->vrf_id();
200 
201  if (aging_table_map_[vrf_id] == NULL) {
202  const VrfEntry *vrf = agent_->vrf_table()->FindVrfFromId(vrf_id);
203  assert(vrf->IsActive() == true);
204  MacAgingTablePtr aging_table(new MacAgingTable(agent_, vrf));
205  aging_table_map_[vrf_id] = aging_table;
206  }
207 
208  aging_table_map_[vrf_id]->Add(mle);
209 
210  if (timer_->running() == false) {
212  boost::bind(&MacAgingPartition::Run, this));
213  }
214 }
215 
217  uint32_t vrf_id = mle->vrf_id();
218  if (aging_table_map_[vrf_id] != NULL) {
219  aging_table_map_[vrf_id]->Delete(mle);
220  }
221 }
222 
224  bool ret = false;
225  MacAgingTableMap::iterator it = aging_table_map_.begin();
226  for (;it != aging_table_map_.end(); it++) {
227  if (it->second.get() && it->second->Run()) {
228  ret = true;
229  }
230  }
231 
232  return ret;
233 }
234 
235 void MacAgingPartition::DeleteVrf(uint32_t id) {
236  aging_table_map_[id].reset();
237 }
238 
240  switch(req->event()) {
242  Add(req->mac_learning_entry());
243  break;
244 
246  Delete(req->mac_learning_entry());
247  break;
248 
250  DeleteVrf(req->vrf_id());
251  break;
252 
253  default:
254  assert(0);
255  }
256  return true;
257 }
void ReadStats(MacAgingEntry *ptr)
Definition: mac_aging.cc:69
boost::shared_ptr< MacAgingEntry > MacAgingEntryPtr
Definition: mac_aging.h:57
uint32_t index() const
Definition: mac_learning.h:92
const MacAddress & mac() const
Definition: mac_learning.h:96
Definition: vrf.h:86
void Trace(const std::string &str, MacAgingEntry *ptr)
Definition: mac_aging.cc:100
MacLearningEntry * last_key_
Definition: mac_aging.h:98
#define kTaskMacAging
Definition: agent.h:343
void set_deleted(bool deleted)
Definition: mac_aging.h:41
uint64_t packets() const
Definition: mac_aging.h:33
bool ShouldBeAged(MacAgingEntry *ptr, uint64_t curr_time)
Definition: mac_aging.cc:83
std::string ToString() const
Definition: mac_address.cc:53
static const uint32_t kMinEntriesPerScan
Definition: mac_aging.h:63
MacAgingTableMap aging_table_map_
Definition: mac_aging.h:136
uint64_t packets_
Definition: mac_aging.h:52
MacLearningEntryPtr mac_learning_entry() const
Definition: mac_aging.h:21
boost::shared_ptr< MacAgingTable > MacAgingTablePtr
Definition: mac_aging.h:113
uint64_t last_modified_time_
Definition: mac_aging.h:53
VrfEntry * FindVrfFromId(size_t index)
Definition: vrf.cc:884
uint32_t CalculateEntriesPerIteration(uint32_t table_size)
Definition: mac_aging.cc:122
Definition: agent.h:358
KSync * ksync() const
Definition: agent.cc:901
virtual ~MacAgingPartition()
Definition: mac_aging.cc:190
virtual ~MacAgingTable()
Definition: mac_aging.cc:46
VrfEntryConstRef vrf_
Definition: mac_aging.h:100
SandeshTraceBufferPtr MacLearningTraceBuf
static const std::string duration_usecs_to_string(const uint64_t usecs)
Definition: time_util.h:62
MacAgingEntryTable aging_table_
Definition: mac_aging.h:97
bool RequestHandler(MacLearningEntryRequestPtr ptr)
Definition: mac_aging.cc:239
MacAgingQueue request_queue_
Definition: mac_aging.h:133
std::pair< MacLearningEntry *, MacAgingEntryPtr > MacAgingPair
Definition: mac_aging.h:64
boost::shared_ptr< MacLearningEntryRequest > MacLearningEntryRequestPtr
void SendDeleteMsg(MacAgingEntry *ptr)
Definition: mac_aging.cc:113
void Enqueue(MacLearningEntryRequestPtr req)
Definition: mac_aging.cc:194
static const uint32_t kMinIterationTimeout
Definition: mac_aging.h:111
MacAgingEntry(MacLearningEntryPtr ptr)
Definition: mac_aging.cc:21
Agent * agent_
Definition: mac_aging.h:96
MacAgingPartition(Agent *agent, uint32_t id)
Definition: mac_aging.cc:178
void set_last_modified_time(uint64_t curr_time)
Definition: mac_aging.h:25
void DeleteVrf(uint32_t id)
Definition: mac_aging.cc:235
VrfTable * vrf_table() const
Definition: agent.h:485
MacAgingTable(Agent *agent, const VrfEntry *)
Definition: mac_aging.cc:42
uint32_t timeout_msec_
Definition: mac_aging.h:99
KSyncBridgeMemory * ksync_bridge_memory() const
Definition: ksync_init.h:82
MacLearningEntryPtr mac_learning_entry_
Definition: mac_aging.h:51
uint64_t last_modified_time() const
Definition: mac_aging.h:29
static uint64_t UTCTimestampUsec()
Definition: time_util.h:13
uint64_t addition_time_
Definition: mac_aging.h:55
void Delete(MacLearningEntryPtr ptr)
Definition: mac_aging.cc:216
bool Start(int time, Handler handler, ErrorHandler error_handler=NULL)
Definition: timer.cc:108
void Add(MacLearningEntryPtr ptr)
Definition: mac_aging.cc:49
void Delete(MacLearningEntryPtr ptr)
Definition: mac_aging.cc:61
void FillSandesh(SandeshMacEntry *sme) const
Definition: mac_aging.cc:27
bool IsActive() const
Definition: agent_db.cc:27
bool running() const
Definition: timer.h:86
bool Enqueue(QueueEntryT entry)
Definition: queue_task.h:248
uint64_t timeout_in_usecs() const
Definition: mac_aging.h:70
static bool DeleteTimer(Timer *Timer)
Definition: timer.cc:222
boost::shared_ptr< MacLearningEntry > MacLearningEntryPtr
void set_packets(uint64_t packets)
Definition: mac_aging.h:37
void Add(MacLearningEntryPtr ptr)
Definition: mac_aging.cc:198