Line data Source code
1 : /*
2 : * Copyright (c) 2014 Juniper Networks, Inc. All rights reserved.
3 : */
4 :
5 : #include <oper/interface_common.h>
6 : #include <uve/prouter_uve_table.h>
7 : #include <uve/agent_uve_base.h>
8 :
9 : using boost::uuids::nil_uuid;
10 :
11 : SandeshTraceBufferPtr ProuterUveTraceBuf(SandeshTraceBufferCreate
12 : ("ProuterUve", 500));
13 :
14 6 : ProuterUveTable::ProuterUveTable(Agent *agent, uint32_t default_intvl)
15 6 : : uve_prouter_map_(), uve_phy_interface_map_(), agent_(agent),
16 6 : physical_device_listener_id_(DBTableBase::kInvalidId),
17 6 : interface_listener_id_(DBTableBase::kInvalidId),
18 6 : pr_timer_last_visited_(nil_uuid()),
19 6 : pr_timer_(TimerManager::CreateTimer
20 6 : (*(agent->event_manager())->io_service(),
21 : "ProuterUveTimer",
22 : TaskScheduler::GetInstance()->GetTaskId(kTaskDBExclude), 0)),
23 6 : pi_timer_last_visited_(""),
24 6 : pi_timer_(TimerManager::CreateTimer
25 6 : (*(agent->event_manager())->io_service(),
26 : "PIUveTimer",
27 : TaskScheduler::GetInstance()->GetTaskId(kTaskDBExclude), 0)),
28 6 : li_timer_last_visited_(nil_uuid()),
29 6 : li_timer_(TimerManager::CreateTimer
30 6 : (*(agent->event_manager())->io_service(),
31 : "LIUveTimer",
32 12 : TaskScheduler::GetInstance()->GetTaskId(kTaskDBExclude), 0)) {
33 :
34 6 : pr_timer_->Start(default_intvl,
35 : boost::bind(&ProuterUveTable::TimerExpiry, this));
36 6 : pi_timer_->Start(default_intvl,
37 : boost::bind(&ProuterUveTable::PITimerExpiry, this));
38 6 : li_timer_->Start(default_intvl,
39 : boost::bind(&ProuterUveTable::LITimerExpiry, this));
40 6 : }
41 :
42 9 : ProuterUveTable::~ProuterUveTable() {
43 6 : TimerCleanup(pr_timer_);
44 6 : TimerCleanup(pi_timer_);
45 6 : TimerCleanup(li_timer_);
46 9 : }
47 :
48 18 : void ProuterUveTable::TimerCleanup(Timer *timer) {
49 18 : if (timer) {
50 18 : timer->Cancel();
51 18 : TimerManager::DeleteTimer(timer);
52 : }
53 18 : }
54 :
55 0 : bool ProuterUveTable::TimerExpiry() {
56 : UveProuterMap::iterator it = uve_prouter_map_.lower_bound
57 0 : (pr_timer_last_visited_);
58 0 : if (it == uve_prouter_map_.end()) {
59 0 : pr_timer_last_visited_ = nil_uuid();
60 0 : return true;
61 : }
62 :
63 0 : uint32_t count = 0;
64 0 : while (it != uve_prouter_map_.end() &&
65 : count < AgentUveBase::kUveCountPerTimer) {
66 0 : ProuterUveEntry* entry = it->second.get();
67 0 : UveProuterMap::iterator prev = it;
68 0 : it++;
69 0 : count++;
70 :
71 0 : if (entry->deleted_) {
72 0 : SendProuterDeleteMsg(entry);
73 0 : if (!entry->renewed_) {
74 0 : uve_prouter_map_.erase(prev);
75 0 : SendProuterVrouterAssociation();
76 : } else {
77 0 : entry->deleted_ = false;
78 0 : entry->renewed_ = false;
79 0 : entry->changed_ = false;
80 0 : SendProuterMsg(entry);
81 : }
82 0 : } else if (entry->changed_) {
83 0 : SendProuterMsg(entry);
84 0 : entry->changed_ = false;
85 : /* Clear renew flag to be on safer side. Not really required */
86 0 : entry->renewed_ = false;
87 : }
88 : }
89 :
90 0 : if (it == uve_prouter_map_.end()) {
91 0 : pr_timer_last_visited_ = nil_uuid();
92 0 : set_expiry_time(agent_->uve()->default_interval(), pr_timer_);
93 : } else {
94 0 : pr_timer_last_visited_ = it->first;
95 0 : set_expiry_time(agent_->uve()->incremental_interval(), pr_timer_);
96 : }
97 : /* Return true to trigger auto-restart of timer */
98 0 : return true;
99 : }
100 :
101 0 : bool ProuterUveTable::PITimerExpiry() {
102 : UvePhyInterfaceMap::iterator it = uve_phy_interface_map_.lower_bound
103 0 : (pi_timer_last_visited_);
104 0 : if (it == uve_phy_interface_map_.end()) {
105 0 : pi_timer_last_visited_ = "";
106 0 : return true;
107 : }
108 :
109 0 : uint32_t count = 0;
110 0 : while (it != uve_phy_interface_map_.end() &&
111 : count < AgentUveBase::kUveCountPerTimer) {
112 0 : PhyInterfaceUveEntry* entry = it->second.get();
113 0 : string cfg_name = it->first;
114 0 : UvePhyInterfaceMap::iterator prev = it;
115 0 : it++;
116 0 : count++;
117 :
118 0 : if (entry->deleted_) {
119 0 : SendPhysicalInterfaceDeleteMsg(cfg_name);
120 0 : if (!entry->renewed_) {
121 0 : uve_phy_interface_map_.erase(prev);
122 : } else {
123 0 : entry->deleted_ = false;
124 0 : entry->renewed_ = false;
125 0 : entry->changed_ = false;
126 0 : SendPhysicalInterfaceMsg(cfg_name, entry);
127 : }
128 0 : } else if (entry->changed_) {
129 0 : SendPhysicalInterfaceMsg(cfg_name, entry);
130 0 : entry->changed_ = false;
131 : /* Clear renew flag to be on safer side. Not really required */
132 0 : entry->renewed_ = false;
133 : }
134 0 : }
135 :
136 0 : if (it == uve_phy_interface_map_.end()) {
137 0 : pi_timer_last_visited_ = "";
138 0 : set_expiry_time(agent_->uve()->default_interval(), pi_timer_);
139 : } else {
140 0 : pi_timer_last_visited_ = it->first;
141 0 : set_expiry_time(agent_->uve()->incremental_interval(), pi_timer_);
142 : }
143 : /* Return true to trigger auto-restart of timer */
144 0 : return true;
145 : }
146 :
147 0 : bool ProuterUveTable::LITimerExpiry() {
148 : LogicalInterfaceMap::iterator it = uve_logical_interface_map_.lower_bound
149 0 : (li_timer_last_visited_);
150 0 : if (it == uve_logical_interface_map_.end()) {
151 0 : li_timer_last_visited_ = nil_uuid();
152 0 : return true;
153 : }
154 :
155 0 : uint32_t count = 0;
156 0 : while (it != uve_logical_interface_map_.end() &&
157 : count < AgentUveBase::kUveCountPerTimer) {
158 0 : LogicalInterfaceUveEntry* entry = it->second.get();
159 0 : boost::uuids::uuid u = it->first;
160 0 : LogicalInterfaceMap::iterator prev = it;
161 0 : it++;
162 0 : count++;
163 :
164 0 : if (entry->deleted_) {
165 0 : SendLogicalInterfaceDeleteMsg(entry->name_);
166 0 : if (!entry->renewed_) {
167 0 : uve_logical_interface_map_.erase(prev);
168 : } else {
169 0 : entry->deleted_ = false;
170 0 : entry->renewed_ = false;
171 0 : entry->changed_ = false;
172 0 : SendLogicalInterfaceMsg(u, entry);
173 : }
174 0 : } else if (entry->changed_) {
175 0 : SendLogicalInterfaceMsg(u, entry);
176 0 : entry->changed_ = false;
177 : /* Clear renew flag to be on safer side. Not really required */
178 0 : entry->renewed_ = false;
179 : }
180 : }
181 :
182 0 : if (it == uve_logical_interface_map_.end()) {
183 0 : li_timer_last_visited_ = nil_uuid();
184 0 : set_expiry_time(agent_->uve()->default_interval(), li_timer_);
185 : } else {
186 0 : li_timer_last_visited_ = it->first;
187 0 : set_expiry_time(agent_->uve()->incremental_interval(), li_timer_);
188 : }
189 : /* Return true to trigger auto-restart of timer */
190 0 : return true;
191 : }
192 :
193 0 : void ProuterUveTable::set_expiry_time(int time, Timer *timer) {
194 0 : if (time != timer->time()) {
195 0 : timer->Reschedule(time);
196 : }
197 0 : }
198 :
199 1 : ProuterUveTable::PhyInterfaceUveEntry::PhyInterfaceUveEntry
200 1 : (const Interface *pintf) :
201 1 : uuid_(pintf->GetUuid()), logical_interface_set_(), changed_(true),
202 1 : deleted_(false), renewed_(false) {
203 1 : Update(pintf);
204 1 : }
205 :
206 2 : void ProuterUveTable::PhyInterfaceUveEntry::Update(const Interface *pintf) {
207 2 : }
208 :
209 1 : ProuterUveTable::ProuterUveEntry::ProuterUveEntry(const PhysicalDevice *p) :
210 1 : name_(p->name()), uuid_(p->uuid()), physical_interface_set_(),
211 1 : changed_(true), deleted_(false), renewed_(false), mastership_(p->master()) {
212 1 : }
213 :
214 1 : ProuterUveTable::LogicalInterfaceUveEntry::LogicalInterfaceUveEntry
215 1 : (const LogicalInterface *li) : name_(li->name()), vlan_(kInvalidVlanId),
216 1 : vmi_list_(), changed_(true), deleted_(false), renewed_(false) {
217 1 : Update(li);
218 1 : }
219 :
220 7 : void ProuterUveTable::LogicalInterfaceUveEntry::Update
221 : (const LogicalInterface *li) {
222 7 : const VlanLogicalInterface *vlif = dynamic_cast
223 7 : <const VlanLogicalInterface *>(li);
224 7 : if (vlif) {
225 7 : vlan_ = vlif->vlan();
226 : } else {
227 0 : vlan_ = kInvalidVlanId;
228 : }
229 7 : changed_ = true;
230 7 : }
231 :
232 1 : ProuterUveTable::ProuterUveEntry::~ProuterUveEntry() {
233 1 : }
234 :
235 1 : void ProuterUveTable::ProuterUveEntry::Reset() {
236 1 : physical_interface_set_.clear();
237 1 : logical_interface_set_.clear();
238 1 : deleted_ = true;
239 1 : renewed_ = false;
240 1 : }
241 :
242 1 : void ProuterUveTable::ProuterUveEntry::AddPhysicalInterface
243 : (const Interface *itf) {
244 1 : InterfaceSet::iterator it = physical_interface_set_.find(itf->name());
245 1 : if (it == physical_interface_set_.end()) {
246 1 : physical_interface_set_.insert(itf->name());
247 1 : changed_ = true;
248 : }
249 1 : }
250 :
251 1 : void ProuterUveTable::ProuterUveEntry::DeletePhysicalInterface
252 : (const Interface *itf) {
253 1 : InterfaceSet::iterator it = physical_interface_set_.find(itf->name());
254 1 : if (it != physical_interface_set_.end()) {
255 0 : physical_interface_set_.erase(it);
256 0 : changed_ = true;
257 : }
258 1 : }
259 :
260 0 : void ProuterUveTable::ProuterUveEntry::AddLogicalInterface
261 : (const LogicalInterface *itf) {
262 : LogicalInterfaceSet::iterator it = logical_interface_set_.find
263 0 : (itf->GetUuid());
264 0 : if (it == logical_interface_set_.end()) {
265 0 : logical_interface_set_.insert(itf->GetUuid());
266 : }
267 0 : }
268 :
269 1 : bool ProuterUveTable::ProuterUveEntry::DeleteLogicalInterface
270 : (const LogicalInterface *itf) {
271 1 : bool deleted = false;
272 1 : LogicalInterfaceSet::iterator it = logical_interface_set_.find(itf->
273 1 : GetUuid());
274 1 : if (it != logical_interface_set_.end()) {
275 0 : logical_interface_set_.erase(it);
276 0 : deleted = true;
277 : }
278 1 : return deleted;
279 : }
280 :
281 1 : ProuterUveTable::ProuterUveEntryPtr ProuterUveTable::Allocate
282 : (const PhysicalDevice *pr) {
283 1 : ProuterUveEntryPtr uve(new ProuterUveEntry(pr));
284 1 : return uve;
285 : }
286 :
287 : ProuterUveTable::ProuterUveEntry *
288 2 : ProuterUveTable::PDEntryToProuterUveEntry(const boost::uuids::uuid &u) const {
289 2 : UveProuterMap::const_iterator it = uve_prouter_map_.find(u);
290 2 : if (it == uve_prouter_map_.end()) {
291 0 : return NULL;
292 : }
293 2 : return it->second.get();
294 : }
295 :
296 1 : ProuterUveTable::PhyInterfaceUveEntry *ProuterUveTable::
297 : NameToPhyInterfaceUveEntry(const string &name) const {
298 1 : UvePhyInterfaceMap::const_iterator it = uve_phy_interface_map_.find(name);
299 1 : if (it != uve_phy_interface_map_.end()) {
300 1 : return it->second.get();
301 : }
302 0 : return NULL;
303 : }
304 :
305 0 : const Interface *ProuterUveTable::NameToInterface(const string &name) const {
306 0 : PhysicalInterfaceKey phy_key(name);
307 0 : Interface *intf = static_cast<PhysicalInterface *>
308 0 : (agent_->interface_table()->FindActiveEntry(&phy_key));
309 0 : if (intf == NULL) {
310 0 : RemotePhysicalInterfaceKey rem_key(name);
311 0 : intf = static_cast<RemotePhysicalInterface *>
312 0 : (agent_->interface_table()->FindActiveEntry(&rem_key));
313 0 : }
314 0 : return intf;
315 0 : }
316 :
317 0 : const PhysicalDevice *ProuterUveTable::InterfaceToProuter
318 : (const Interface *intf) {
319 0 : PhysicalDevice *pde = NULL;
320 : const RemotePhysicalInterface *rpintf;
321 : const PhysicalInterface *pintf;
322 0 : if (intf->type() == Interface::REMOTE_PHYSICAL) {
323 0 : rpintf = static_cast<const RemotePhysicalInterface *>(intf);
324 0 : pde = rpintf->physical_device();
325 0 : } else if (intf->type() == Interface::PHYSICAL) {
326 0 : pintf = static_cast<const PhysicalInterface *>(intf);
327 0 : pde = pintf->physical_device();
328 : }
329 0 : return pde;
330 : }
331 :
332 0 : void ProuterUveTable::LogicalInterfaceUveEntry::FillVmInterfaceList
333 : (vector<string> &vmi_list) const {
334 0 : ProuterUveTable::InterfaceSet::iterator vit = vmi_list_.begin();
335 0 : while (vit != vmi_list_.end()) {
336 0 : vmi_list.push_back((*vit));
337 0 : ++vit;
338 : }
339 0 : return;
340 : }
341 :
342 0 : void ProuterUveTable::PhyInterfaceUveEntry::FillLogicalInterfaceList
343 : (vector<string> &list) const {
344 : ProuterUveTable::LogicalInterfaceSet::iterator it =
345 0 : logical_interface_set_.begin();
346 0 : while (it != logical_interface_set_.end()) {
347 0 : list.push_back((to_string(*it)));
348 0 : ++it;
349 : }
350 0 : return;
351 : }
352 :
353 0 : void ProuterUveTable::FrameProuterMsg(ProuterUveEntry *entry,
354 : ProuterData *uve) const {
355 0 : vector<string> phy_if_list;
356 0 : vector<string> logical_list;
357 0 : vector<string> empty_agent_list;
358 : /* We are using hostname instead of fq-name because Prouter UVE sent by
359 : * other modules to send topology information uses hostname and we want
360 : * both these information to be seen in same UVE */
361 0 : uve->set_name(entry->name_);
362 0 : uve->set_uuid(to_string(entry->uuid_));
363 0 : uve->set_agent_name(agent_->agent_name());
364 0 : InterfaceSet::iterator pit = entry->physical_interface_set_.begin();
365 0 : while (pit != entry->physical_interface_set_.end()) {
366 0 : phy_if_list.push_back(*pit);
367 0 : ++pit;
368 : }
369 0 : uve->set_physical_interface_list(phy_if_list);
370 :
371 :
372 : LogicalInterfaceSet::const_iterator lit = entry->logical_interface_set_.
373 0 : begin();
374 :
375 0 : while (lit != entry->logical_interface_set_.end()) {
376 0 : logical_list.push_back(to_string(*lit));
377 0 : ++lit;
378 : }
379 0 : uve->set_logical_interface_list(logical_list);
380 0 : if (entry->mastership_) {
381 0 : vector<string> agent_list;
382 0 : agent_list.push_back(agent_->agent_name());
383 0 : if (agent_->tsn_enabled()) {
384 0 : uve->set_tsn_agent_list(agent_list);
385 0 : } else if (agent_->tor_agent_enabled()) {
386 0 : uve->set_connected_agent_list(agent_list);
387 : }
388 0 : } else {
389 : /* Send Empty list */
390 0 : if (agent_->tsn_enabled()) {
391 0 : uve->set_tsn_agent_list(empty_agent_list);
392 0 : } else if (agent_->tor_agent_enabled()) {
393 0 : uve->set_connected_agent_list(empty_agent_list);
394 : }
395 : }
396 0 : vnsConstants vnsVrouterType;
397 0 : if (agent_->vcpe_gateway_mode()) {
398 0 : uve->set_gateway_mode(vnsVrouterType.VrouterAgentGatewayModeMap.at
399 0 : (VrouterAgentGatewayMode::VCPE));
400 0 : } else if ((agent_->server_gateway_mode()) ||
401 0 : (agent_->pbb_gateway_mode())) {
402 0 : uve->set_gateway_mode(vnsVrouterType.VrouterAgentGatewayModeMap.at
403 0 : (VrouterAgentGatewayMode::SERVER));
404 : } else {
405 0 : uve->set_gateway_mode(vnsVrouterType.VrouterAgentGatewayModeMap.at
406 0 : (VrouterAgentGatewayMode::NONE));
407 : }
408 0 : }
409 :
410 0 : bool ProuterUveTable::SendProuterMsg(ProuterUveEntry *entry) {
411 0 : ProuterData uve;
412 0 : FrameProuterMsg(entry, &uve);
413 0 : DispatchProuterMsg(uve);
414 0 : return true;
415 0 : }
416 :
417 0 : void ProuterUveTable::SendProuterDeleteMsg(ProuterUveEntry *e) {
418 0 : ProuterData uve;
419 0 : uve.set_name(e->name_);
420 0 : uve.set_deleted(true);
421 0 : DispatchProuterMsg(uve);
422 0 : }
423 :
424 0 : void ProuterUveTable::MarkPhysicalDeviceChanged(const PhysicalDevice *pde) {
425 0 : if (pde && !pde->IsDeleted()) {
426 0 : ProuterUveEntry *entry = PDEntryToProuterUveEntry(pde->uuid());
427 0 : if (entry) {
428 0 : entry->changed_ = true;
429 : }
430 : }
431 0 : }
432 :
433 0 : void ProuterUveTable::SendProuterMsgFromPhyInterface(const Interface *pi) {
434 0 : const PhysicalDevice *pde = InterfaceToProuter(pi);
435 0 : MarkPhysicalDeviceChanged(pde);
436 0 : }
437 :
438 0 : void ProuterUveTable::DispatchProuterMsg(const ProuterData &uve) {
439 0 : UveProuterAgent::Send(uve);
440 0 : }
441 :
442 1 : void ProuterUveTable::SendProuterVrouterAssociation() {
443 1 : vector<string> plist;
444 1 : UveProuterMap::iterator it = uve_prouter_map_.begin();
445 2 : while (it != uve_prouter_map_.end()) {
446 1 : ProuterUveEntry* entry = it->second.get();
447 1 : plist.push_back(entry->name_);
448 1 : ++it;
449 : }
450 1 : agent_->uve()->vrouter_uve_entry()->SendVrouterProuterAssociation(plist);
451 1 : }
452 :
453 1 : ProuterUveTable::ProuterUveEntry* ProuterUveTable::AddHandler
454 : (const PhysicalDevice *p) {
455 1 : ProuterUveEntryPtr uve = Allocate(p);
456 1 : pair<UveProuterMap::iterator, bool> ret;
457 1 : ret = uve_prouter_map_.insert(UveProuterPair(p->uuid(), uve));
458 1 : UveProuterMap::iterator it = ret.first;
459 1 : ProuterUveEntry *entry = it->second.get();
460 1 : entry->changed_ = true;
461 1 : entry->mastership_ = p->master();
462 1 : if (entry->deleted_) {
463 0 : entry->renewed_ = true;
464 : }
465 1 : if (!entry->renewed_) {
466 1 : SendProuterVrouterAssociation();
467 : }
468 1 : return entry;
469 1 : }
470 :
471 1 : void ProuterUveTable::DeleteHandler(const PhysicalDevice *p) {
472 1 : UveProuterMap::iterator it = uve_prouter_map_.find(p->uuid());
473 1 : if (it == uve_prouter_map_.end()) {
474 0 : return;
475 : }
476 :
477 1 : ProuterUveEntry* entry = it->second.get();
478 : /* Reset all the non-key fields of entry so that it has proper values in
479 : * case it gets reused. Also update deleted_ and renewed_ flags */
480 1 : entry->Reset();
481 : }
482 :
483 1 : void ProuterUveTable::MarkDeletedLogical(const LogicalInterface *itf) {
484 1 : LogicalInterfaceMap::iterator it = uve_logical_interface_map_.find(itf->
485 1 : GetUuid());
486 1 : if (it != uve_logical_interface_map_.end()) {
487 1 : LogicalInterfaceUveEntry *entry = it->second.get();
488 1 : entry->deleted_ = true;
489 : }
490 1 : }
491 :
492 7 : void ProuterUveTable::AddUpdateLogicalInterface(const LogicalInterface *itf) {
493 7 : LogicalInterfaceMap::iterator it = uve_logical_interface_map_.find(itf->
494 7 : GetUuid());
495 7 : if (it == uve_logical_interface_map_.end()) {
496 1 : LogicalInterfaceUveEntryPtr uve(new LogicalInterfaceUveEntry(itf));
497 1 : uve_logical_interface_map_.insert(LogicalInterfacePair(itf->GetUuid(),
498 : uve));
499 1 : return;
500 1 : } else {
501 6 : LogicalInterfaceUveEntry *entry = it->second.get();
502 6 : entry->Update(itf);
503 : }
504 : }
505 :
506 1 : void ProuterUveTable::MarkDeletedPhysical(const Interface *pintf) {
507 1 : UvePhyInterfaceMap::iterator it = uve_phy_interface_map_.find(pintf->
508 1 : name());
509 1 : PhyInterfaceUveEntry *entry = NULL;
510 1 : if (it != uve_phy_interface_map_.end()) {
511 1 : entry = it->second.get();
512 1 : entry->deleted_ = true;
513 : }
514 1 : }
515 :
516 1 : void ProuterUveTable::AddLogicalToPhysical(const Interface *pintf,
517 : const LogicalInterface *intf) {
518 1 : UvePhyInterfaceMap::iterator it = uve_phy_interface_map_.find(pintf->
519 1 : name());
520 1 : PhyInterfaceUveEntry *ientry = NULL;
521 1 : if (it == uve_phy_interface_map_.end()) {
522 0 : PhyInterfaceUveEntryPtr entry(new PhyInterfaceUveEntry(pintf));
523 0 : uve_phy_interface_map_.insert(UvePhyInterfacePair(pintf->name(),
524 : entry));
525 0 : ientry = entry.get();
526 0 : } else {
527 1 : ientry = it->second.get();
528 : }
529 : LogicalInterfaceSet::iterator lit = ientry->logical_interface_set_.
530 1 : find(intf->GetUuid());
531 1 : if (lit == ientry->logical_interface_set_.end()) {
532 1 : ientry->logical_interface_set_.insert(intf->GetUuid());
533 1 : ientry->changed_ = true;
534 : }
535 1 : }
536 :
537 0 : void ProuterUveTable::AddProuterLogicalInterface
538 : (const PhysicalDevice *p, const LogicalInterface *intf) {
539 0 : UveProuterMap::iterator it = uve_prouter_map_.find(p->uuid());
540 0 : if (it == uve_prouter_map_.end()) {
541 0 : return;
542 : }
543 :
544 0 : ProuterUveEntry* entry = it->second.get();
545 0 : entry->AddLogicalInterface(intf);
546 0 : entry->changed_ = true;
547 : }
548 :
549 1 : void ProuterUveTable::DeleteLogicalFromPhysical(const string &name,
550 : const LogicalInterface *intf) {
551 1 : PhyInterfaceUveEntry *entry = NameToPhyInterfaceUveEntry(name);
552 1 : if (entry != NULL) {
553 : LogicalInterfaceSet::iterator it = entry->logical_interface_set_.
554 1 : find(intf->GetUuid());
555 1 : if (it != entry->logical_interface_set_.end()) {
556 1 : entry->logical_interface_set_.erase(it);
557 1 : entry->changed_ = true;
558 : }
559 : }
560 1 : }
561 :
562 1 : void ProuterUveTable::DeleteProuterLogicalInterface
563 : (const boost::uuids::uuid &u, const LogicalInterface *intf) {
564 1 : UveProuterMap::iterator it = uve_prouter_map_.find(u);
565 1 : if (it == uve_prouter_map_.end()) {
566 0 : return;
567 : }
568 :
569 1 : ProuterUveEntry* entry = it->second.get();
570 1 : bool deleted = entry->DeleteLogicalInterface(intf);
571 1 : if (deleted) {
572 0 : entry->changed_ = true;
573 : }
574 : }
575 :
576 2 : void ProuterUveTable::PhysicalDeviceNotify(DBTablePartBase *partition,
577 : DBEntryBase *e) {
578 2 : const PhysicalDevice *pr = static_cast<const PhysicalDevice *>(e);
579 : PhysicalDeviceState *state = static_cast<PhysicalDeviceState *>
580 2 : (e->GetState(partition->parent(), physical_device_listener_id_));
581 2 : if (e->IsDeleted()) {
582 1 : if (state) {
583 : /* Uve Msg send is part of Delete API */
584 1 : DeleteHandler(pr);
585 1 : e->ClearState(partition->parent(), physical_device_listener_id_);
586 1 : delete state;
587 : }
588 : } else {
589 1 : if (!state) {
590 1 : state = new PhysicalDeviceState();
591 1 : e->SetState(partition->parent(), physical_device_listener_id_,
592 : state);
593 : /* Uve Msg send is part of Add API */
594 1 : AddHandler(pr);
595 : } else {
596 : /* For Change notifications send only the msg */
597 0 : ProuterUveEntry *entry = PDEntryToProuterUveEntry(pr->uuid());
598 0 : entry->mastership_ = pr->master();
599 0 : entry->changed_ = true;
600 : }
601 : }
602 2 : }
603 :
604 1 : void ProuterUveTable::DeletePhysicalFromProuter(const Interface *intf,
605 : const boost::uuids::uuid &u) {
606 1 : ProuterUveEntry *entry = PDEntryToProuterUveEntry(u);
607 1 : if (!entry) {
608 0 : return;
609 : }
610 1 : entry->DeletePhysicalInterface(intf);
611 1 : entry->changed_ = true;
612 : }
613 :
614 2 : void ProuterUveTable::AddUpdatePhysicalInterface(const Interface *intf) {
615 2 : UvePhyInterfaceMap::iterator it = uve_phy_interface_map_.find(intf->name());
616 2 : if (it == uve_phy_interface_map_.end()) {
617 1 : PhyInterfaceUveEntryPtr uve(new PhyInterfaceUveEntry(intf));
618 1 : uve_phy_interface_map_.insert(UvePhyInterfacePair(intf->name(), uve));
619 1 : return;
620 1 : }
621 1 : PhyInterfaceUveEntry *entry = it->second.get();
622 1 : entry->Update(intf);
623 : }
624 :
625 2 : void ProuterUveTable::PhysicalInterfaceHandler(const Interface *intf,
626 : const boost::uuids::uuid &u) {
627 2 : if (intf->IsDeleted()) {
628 1 : MarkDeletedPhysical(intf);
629 : }
630 : /* Ignore notifications for PhysicalInterface if it has no
631 : PhysicalDevice */
632 2 : if (u == nil_uuid()) {
633 1 : return;
634 : }
635 1 : ProuterUveEntry *entry = PDEntryToProuterUveEntry(u);
636 1 : if (entry == NULL) {
637 : /* We hit this condition when physical-device is deleted before
638 : * physical interface */
639 0 : return;
640 : }
641 1 : if (intf->IsDeleted()) {
642 0 : entry->DeletePhysicalInterface(intf);
643 : } else {
644 1 : entry->AddPhysicalInterface(intf);
645 : }
646 : }
647 :
648 2 : void ProuterUveTable::VMInterfaceAdd(const VmInterface *vmi) {
649 : LogicalInterfaceUveEntry *entry;
650 2 : const boost::uuids::uuid li = vmi->logical_interface();
651 2 : LogicalInterfaceMap::iterator it = uve_logical_interface_map_.find(li);
652 2 : if (it != uve_logical_interface_map_.end()) {
653 2 : entry = it->second.get();
654 : } else {
655 : LogicalInterface *intf;
656 0 : VlanLogicalInterfaceKey key(li, "");
657 0 : intf = static_cast<LogicalInterface *>
658 0 : (agent_->interface_table()->FindActiveEntry(&key));
659 0 : if (!intf) {
660 0 : return;
661 : }
662 0 : LogicalInterfaceUveEntryPtr uve(new LogicalInterfaceUveEntry(intf));
663 0 : uve_logical_interface_map_.insert(LogicalInterfacePair(li, uve));
664 0 : entry = uve.get();
665 0 : }
666 2 : InterfaceSet::iterator vit = entry->vmi_list_.find(vmi->cfg_name());
667 2 : if (vit == entry->vmi_list_.end()) {
668 2 : entry->vmi_list_.insert(vmi->cfg_name());
669 2 : entry->changed_ = true;
670 : }
671 : }
672 :
673 17 : void ProuterUveTable::VMInterfaceRemove(const boost::uuids::uuid &li,
674 : const VmInterface *vmi) {
675 17 : LogicalInterfaceMap::iterator it = uve_logical_interface_map_.find(li);
676 17 : if (it != uve_logical_interface_map_.end()) {
677 2 : LogicalInterfaceUveEntry *entry = it->second.get();
678 : ProuterUveTable::InterfaceSet::iterator vit = entry->vmi_list_.find
679 2 : (vmi->cfg_name());
680 2 : if (vit != entry->vmi_list_.end()) {
681 0 : entry->vmi_list_.erase(vit);
682 0 : entry->changed_ = true;
683 : }
684 : }
685 17 : }
686 :
687 71 : void ProuterUveTable::VmInterfaceHandler(DBTablePartBase *partition,
688 : DBEntryBase *e) {
689 : VmInterfaceState *state = static_cast<VmInterfaceState *>
690 71 : (e->GetState(partition->parent(), interface_listener_id_));
691 71 : const VmInterface *intf = static_cast<const VmInterface *>(e);
692 71 : if (e->IsDeleted()) {
693 17 : if (state) {
694 17 : VMInterfaceRemove(state->logical_interface_, intf);
695 17 : e->ClearState(partition->parent(), interface_listener_id_);
696 17 : delete state;
697 : }
698 17 : return;
699 : }
700 54 : if (!state) {
701 17 : state = new VmInterfaceState();
702 17 : e->SetState(partition->parent(), interface_listener_id_, state);
703 : }
704 54 : if (state->logical_interface_ != intf->logical_interface()) {
705 2 : if (state->logical_interface_ != nil_uuid()) {
706 0 : VMInterfaceRemove(state->logical_interface_, intf);
707 : }
708 2 : state->logical_interface_ = intf->logical_interface();
709 : }
710 54 : if (intf->logical_interface() != nil_uuid()) {
711 2 : VMInterfaceAdd(intf);
712 : }
713 : }
714 :
715 98 : void ProuterUveTable::InterfaceNotify(DBTablePartBase *partition,
716 : DBEntryBase *e) {
717 98 : const Interface *intf = static_cast<const Interface *>(e);
718 98 : const LogicalInterface *lintf = NULL;
719 98 : const RemotePhysicalInterface *rpintf = NULL;
720 98 : const PhysicalInterface *pintf = NULL;
721 98 : const Interface *physical_interface = NULL;
722 98 : PhysicalDevice *pde = NULL;
723 98 : if (intf->type() == Interface::REMOTE_PHYSICAL) {
724 0 : rpintf = static_cast<const RemotePhysicalInterface *>(intf);
725 0 : pde = rpintf->physical_device();
726 98 : } else if (intf->type() == Interface::LOGICAL) {
727 8 : lintf = static_cast<const LogicalInterface *>(intf);
728 8 : physical_interface = lintf->physical_interface();
729 8 : pde = lintf->physical_device();
730 90 : } else if (intf->type() == Interface::PHYSICAL) {
731 13 : pintf = static_cast<const PhysicalInterface *>(intf);
732 : /* Ignore PhysicalInterface notifications if it is not of subtype
733 : * CONFIG */
734 13 : if (pintf->subtype() != PhysicalInterface::CONFIG) {
735 10 : return;
736 : }
737 3 : pde = pintf->physical_device();
738 77 : } else if (intf->type() == Interface::VM_INTERFACE) {
739 71 : VmInterfaceHandler(partition, e);
740 71 : return;
741 : } else {
742 : /* Ignore notifications for interface which are not
743 : RemotePhysical/Logical */
744 6 : return;
745 : }
746 : ProuterInterfaceState *state = static_cast<ProuterInterfaceState *>
747 11 : (e->GetState(partition->parent(), interface_listener_id_));
748 11 : if (e->IsDeleted()) {
749 2 : if (state) {
750 2 : if (pintf) {
751 1 : PhysicalInterfaceHandler(pintf, state->physical_device_);
752 1 : } else if (rpintf) {
753 0 : PhysicalInterfaceHandler(rpintf, state->physical_device_);
754 1 : } else if (lintf) {
755 1 : if (!state->physical_interface_.empty()) {
756 0 : DeleteLogicalFromPhysical(state->physical_interface_,
757 : lintf);
758 : }
759 1 : if (state->physical_device_ != nil_uuid()) {
760 0 : DeleteProuterLogicalInterface(state->physical_device_,
761 : lintf);
762 : }
763 1 : MarkDeletedLogical(lintf);
764 : }
765 2 : e->ClearState(partition->parent(), interface_listener_id_);
766 2 : delete state;
767 : }
768 : } else {
769 9 : if (!state) {
770 2 : state = new ProuterInterfaceState();
771 2 : e->SetState(partition->parent(), interface_listener_id_, state);
772 : }
773 9 : boost::uuids::uuid pde_uuid = nil_uuid();
774 9 : if (pde) {
775 6 : pde_uuid = pde->uuid();
776 : }
777 9 : string pname;
778 9 : if (physical_interface) {
779 6 : pname = physical_interface->name();
780 : }
781 9 : if (intf->type() == Interface::LOGICAL) {
782 7 : if (state->physical_interface_ != pname) {
783 2 : if (!state->physical_interface_.empty()) {
784 1 : DeleteLogicalFromPhysical(state->physical_interface_,
785 : lintf);
786 : }
787 2 : if (physical_interface) {
788 1 : AddLogicalToPhysical(physical_interface, lintf);
789 : }
790 2 : state->physical_interface_ = pname;
791 : }
792 7 : if (state->physical_device_ != pde_uuid) {
793 2 : if (state->physical_device_ != nil_uuid()) {
794 1 : DeleteProuterLogicalInterface(state->physical_device_,
795 : lintf);
796 : }
797 2 : if (!physical_interface && pde) {
798 0 : AddProuterLogicalInterface(pde, lintf);
799 : }
800 2 : state->physical_device_ = pde_uuid;
801 : }
802 7 : AddUpdateLogicalInterface(lintf);
803 : } else {
804 2 : if (state->physical_device_ != pde_uuid) {
805 2 : if (state->physical_device_ != nil_uuid()) {
806 1 : DeletePhysicalFromProuter(intf, state->physical_device_);
807 : }
808 2 : if (pde) {
809 1 : if (pintf) {
810 1 : PhysicalInterfaceHandler(pintf, pde->uuid());
811 0 : } else if (rpintf) {
812 0 : PhysicalInterfaceHandler(rpintf, pde->uuid());
813 : }
814 : }
815 2 : state->physical_device_ = pde_uuid;
816 : }
817 2 : AddUpdatePhysicalInterface(intf);
818 : }
819 9 : }
820 : }
821 :
822 3 : void ProuterUveTable::RegisterDBClients() {
823 3 : PhysicalDeviceTable *pd_table = agent_->physical_device_table();
824 3 : physical_device_listener_id_ = pd_table->Register
825 3 : (boost::bind(&ProuterUveTable::PhysicalDeviceNotify, this, _1, _2));
826 :
827 3 : InterfaceTable *i_table = agent_->interface_table();
828 3 : interface_listener_id_ = i_table->Register
829 3 : (boost::bind(&ProuterUveTable::InterfaceNotify, this, _1, _2));
830 3 : }
831 :
832 6 : void ProuterUveTable::Shutdown(void) {
833 6 : if (physical_device_listener_id_ != DBTableBase::kInvalidId)
834 3 : agent_->physical_device_table()->
835 3 : Unregister(physical_device_listener_id_);
836 6 : if (interface_listener_id_ != DBTableBase::kInvalidId)
837 3 : agent_->interface_table()->Unregister(interface_listener_id_);
838 6 : }
839 :
840 0 : void ProuterUveTable::SendLogicalInterfaceDeleteMsg(const string &config_name) {
841 0 : UveLogicalInterfaceAgent uve;
842 0 : uve.set_name(config_name);
843 0 : uve.set_deleted(true);
844 0 : DispatchLogicalInterfaceMsg(uve);
845 0 : }
846 :
847 0 : void ProuterUveTable::SendLogicalInterfaceMsg(const boost::uuids::uuid &u,
848 : LogicalInterfaceUveEntry *entry) {
849 0 : UveLogicalInterfaceAgent uve;
850 0 : vector<string> list;
851 :
852 0 : uve.set_name(to_string(u));
853 0 : uve.set_config_name(entry->name_);
854 0 : uve.set_vlan(entry->vlan_);
855 :
856 0 : entry->FillVmInterfaceList(list);
857 0 : uve.set_vm_interface_list(list);
858 :
859 0 : DispatchLogicalInterfaceMsg(uve);
860 0 : }
861 :
862 0 : void ProuterUveTable::DispatchLogicalInterfaceMsg
863 : (const UveLogicalInterfaceAgent &uve) {
864 0 : UveLogicalInterfaceAgentTrace::Send(uve);
865 0 : }
866 :
867 0 : void ProuterUveTable::SendPhysicalInterfaceDeleteMsg(const string &cfg_name) {
868 0 : UvePhysicalInterfaceAgent uve;
869 0 : uve.set_name(cfg_name);
870 0 : uve.set_deleted(true);
871 0 : DispatchPhysicalInterfaceMsg(uve);
872 0 : }
873 :
874 0 : void ProuterUveTable::SendPhysicalInterfaceMsg(const string &cfg_name,
875 : PhyInterfaceUveEntry *entry) {
876 0 : UvePhysicalInterfaceAgent uve;
877 0 : vector<string> list;
878 :
879 0 : uve.set_name(cfg_name);
880 0 : uve.set_uuid(to_string(entry->uuid_));
881 :
882 0 : entry->FillLogicalInterfaceList(list);
883 0 : uve.set_logical_interface_list(list);
884 :
885 0 : DispatchPhysicalInterfaceMsg(uve);
886 0 : }
887 :
888 0 : void ProuterUveTable::DispatchPhysicalInterfaceMsg
889 : (const UvePhysicalInterfaceAgent &uve) {
890 0 : UvePhysicalInterfaceAgentTrace::Send(uve);
891 0 : }
892 :
893 0 : void ProuterUveTable::UpdateMastership(const boost::uuids::uuid &u, bool value)
894 : {
895 0 : ProuterUveEntry *entry = PDEntryToProuterUveEntry(u);
896 0 : if (entry == NULL) {
897 0 : string status = " false";
898 0 : if (value) {
899 0 : status.assign(" true");
900 : }
901 0 : string msg = "Mastership update failed for " + to_string(u) + status;
902 0 : PROUTER_UVE_TRACE(msg);
903 0 : return;
904 0 : }
905 0 : if (entry->mastership_ != value) {
906 0 : entry->mastership_ = value;
907 0 : entry->changed_ = true;
908 : }
909 : }
|