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