OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
vxlan_routing_manager.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018 Juniper Networks, Inc. All rights reserved.
3  */
4 
5 #include <boost/uuid/uuid_io.hpp>
6 #include <cmn/agent_cmn.h>
7 
8 #include <base/logging.h>
9 #include <oper/operdb_init.h>
10 #include <oper/route_common.h>
11 #include <oper/vrf.h>
12 #include <oper/bridge_route.h>
14 #include <oper/evpn_route.h>
15 #include <oper/agent_route.h>
17 #include <oper/vn.h>
18 #include <oper/vrf.h>
20 #include <oper/tunnel_nh.h> //for tunnel interception
21 
22 using namespace std;
23 
25  VrfEntry *vrf) {
26  inet4_table_ = vrf->GetInet4UnicastRouteTable();
27  inet6_table_ = vrf->GetInet6UnicastRouteTable();
28  evpn_table_ = vrf->GetEvpnRouteTable();
29  std::string nm4 = std::string("vxlan_lstnr.") + inet4_table_->name();
30  std::string nm6 = std::string("vxlan_lstnr.") + inet6_table_->name();
31  std::string nme = std::string("vxlan_lstnr.") + evpn_table_->name();
32 
33  inet4_id_ = inet4_table_->
34  Register(boost::bind(&VxlanRoutingManager::RouteNotify,
35  mgr, _1, _2), nm4);
36  inet6_id_ = inet6_table_->
37  Register(boost::bind(&VxlanRoutingManager::RouteNotify,
38  mgr, _1, _2), nm6);
39  evpn_id_ = evpn_table_->
40  Register(boost::bind(&VxlanRoutingManager::RouteNotify,
41  mgr, _1, _2), nme);
42 }
43 
45  evpn_table_->Unregister(evpn_id_);
46  inet4_table_->Unregister(inet4_id_);
47  inet6_table_->Unregister(inet6_id_);
48 }
49 
51  vmi_list_(), is_routing_vn_(false),
52  logical_router_uuid_(boost::uuids::nil_uuid()), mgr_(mgr) {
53 }
54 
56 }
57 
58 void VxlanRoutingVnState::AddVmi(const VnEntry *vn, const VmInterface *vmi) {
59  if (vmi->logical_router_uuid() == boost::uuids::nil_uuid()) {
60  LOG(ERROR, "Error in VxlanRoutingManager::AddVmi"
61  << ", vmi->logical_router_uuid() == boost::uuids::nil_uuid()");
62  assert(vmi->logical_router_uuid() != boost::uuids::nil_uuid());
63  }
64  VmiListIter it = vmi_list_.find(vmi);
65  if (it != vmi_list_.end()) {
66  return;
67  }
68 
69  vmi_list_.insert(vmi);
70  if ((logical_router_uuid_ != vmi->logical_router_uuid()) &&
71  (*(vmi_list_.begin()) == vmi)) {
72  mgr_->BridgeVnNotify(vn, this);
73  }
74 }
75 
76 void VxlanRoutingVnState::DeleteVmi(const VnEntry *vn, const VmInterface *vmi) {
77  VmiListIter it = vmi_list_.find(vmi);
78  if (it == vmi_list_.end()) {
79  return;
80  }
81  vmi_list_.erase(vmi);
82  mgr_->BridgeVnNotify(vn, this);
83 }
84 
86  vn_entry_(NULL), logical_router_uuid_(boost::uuids::nil_uuid()) {
87 }
88 
90 }
91 
93  if (vmi_list_.size() == 0)
94  return boost::uuids::nil_uuid();
95 
96  return (*(vmi_list_.begin()))->logical_router_uuid();
97 }
98 
100  VxlanRoutingManager *mgr, Agent *agent) :
101  AgentRouteWalker(name, agent), mgr_(mgr) {
102 }
103 
105 }
106 
107 // Only take notification of bridge inet routes.
108 // Change in them will trigger change in rest.
110  DBEntryBase *e) {
111  // Now route leaking is triggered by changes in the Inet table of
112  // a bridge VRF instance
113  const InetUnicastRouteEntry *inet_rt =
114  dynamic_cast<const InetUnicastRouteEntry*>(e);
115  if (inet_rt) {
116  const VrfEntry *vrf = inet_rt->vrf();
117  if (vrf && vrf->vn() && !mgr_->IsRoutingVrf(vrf)) {
118  mgr_->InetRouteNotify(partition, e);
119  }
120  }
121  return true;
122 }
123 
125  mgr_(mgr), lr_vrf_info_map_(), vn_lr_set_(),
126  inet4_table_walker_(), inet6_table_walker_() {
127 }
128 
130 }
131 
133  InetUnicastAgentRouteTable *inet4_table,
134  InetUnicastAgentRouteTable *inet6_table) {
135  // Inet 4
136  {
137  DBTable::DBTableWalkRef walk_ref;
138  InetTableWalker::iterator it = inet4_table_walker_.find(inet4_table);
139  if (it == inet4_table_walker_.end()) {
140  walk_ref = inet4_table->
141  AllocWalker(boost::bind(&VxlanRoutingManager::RouteNotify,
142  mgr_, _1, _2),
144  this, _1, _2));
145  inet4_table_walker_[inet4_table] = walk_ref;
146  } else {
147  walk_ref = it->second;
148  }
149  inet4_table->WalkAgain(walk_ref);
150  //Every time walk is issued for bridge table revisit subnet routes
151  mgr_->HandleSubnetRoute(inet4_table->vrf_entry());
152  }
153  // Inet 6
154  {
155  DBTable::DBTableWalkRef walk_ref;
156  InetTableWalker::iterator it = inet6_table_walker_.find(inet6_table);
157  if (it == inet6_table_walker_.end()) {
158  walk_ref = inet6_table->
159  AllocWalker(boost::bind(&VxlanRoutingManager::RouteNotify,
160  mgr_, _1, _2),
162  this, _1, _2));
163  inet6_table_walker_[inet6_table] = walk_ref;
164  } else {
165  walk_ref = it->second;
166  }
167  inet6_table->WalkAgain(walk_ref);
168  //Every time walk is issued for bridge table revisit subnet routes
169  mgr_->HandleSubnetRoute(inet6_table->vrf_entry());
170  }
171 }
172 
174  const VnEntry *vn, bool update, bool withdraw) {
175  if (lr_uuid == boost::uuids::nil_uuid())
176  return;
177  VxlanRoutingVrfMapper::RoutedVrfInfo &routing_vrf_info =
178  lr_vrf_info_map_[lr_uuid];
179  const VrfEntry *routing_vrf = routing_vrf_info.routing_vrf_;
180  DBTable::DBTableWalkRef walk_ref;
181  EvpnAgentRouteTable *evpn_table = NULL;
182  if (withdraw) {
183  const VrfEntry *bridge_vrf = vn->GetVrf();
184  if (bridge_vrf && routing_vrf) {
185  evpn_table =
186  static_cast<EvpnAgentRouteTable *>(
187  bridge_vrf->GetEvpnRouteTable());
188  }
189  if (!evpn_table) {
190  return;
191  }
192  walk_ref = evpn_table->
194  mgr_, routing_vrf, _1, _2),
196  this, _1, _2));
197  evpn_table->WalkAgain(walk_ref);
198  } else {
199  if (routing_vrf) {
200  evpn_table =
201  static_cast<EvpnAgentRouteTable *>(
202  routing_vrf->GetEvpnRouteTable());
203  }
204  if (!evpn_table) {
205  return;
206  }
207 
208  walk_ref = evpn_table->
209  AllocWalker(boost::bind(&VxlanRoutingManager::LeakRoutesIntoBridgeTables,
210  mgr_, _1, _2, lr_uuid, vn, update),
212  this, _1, _2));
213  evpn_table->WalkAgain(walk_ref);
214  }
215 }
216 
218  DBTableBase *partition) {
219  if (walk_ref.get() != NULL)
220  (static_cast<DBTable *>(partition))->ReleaseWalker(walk_ref);
221 }
222 
224  DBTableBase *partition) {
225  const InetUnicastAgentRouteTable *table = static_cast<const InetUnicastAgentRouteTable *>
226  (walk_ref->table());
227  InetTableWalker::iterator it = inet4_table_walker_.find(table);
228  if(it == inet4_table_walker_.end()) {
229  LOG(ERROR, "Error in VxlanRoutingManager::BridgeInet4RouteWalkDone"
230  << ", it == inet4_table_walker_.end()");
231  assert(it != inet4_table_walker_.end());
232  }
233  inet4_table_walker_.erase(it);
234 }
235 
237  DBTableBase *partition) {
238  const InetUnicastAgentRouteTable *table = static_cast<const InetUnicastAgentRouteTable *>
239  (walk_ref->table());
240  InetTableWalker::iterator it = inet6_table_walker_.find(table);
241  if(it == inet6_table_walker_.end()){
242  LOG(ERROR, "Error in VxlanRoutingManager::BridgeInet6RouteWalkDone"
243  << ", it == inet6_table_walker_.end()");
244  assert(it != inet6_table_walker_.end());
245  }
246 
247  inet6_table_walker_.erase(it);
248 }
249 
251 (const VxlanRoutingVrfMapper::RoutedVrfInfo &routed_vrf_info)
252 {
253  // Start walk on all l3 tables
255  routed_vrf_info.bridge_vn_list_.begin();
256  while (it != routed_vrf_info.bridge_vn_list_.end()) {
257  const VnEntry *vn = static_cast<const VnEntry *>(*it);
258  const VrfEntry *vrf = vn->GetVrf();
259  if (vrf) {
260  InetUnicastAgentRouteTable *inet4_table =
261  static_cast<InetUnicastAgentRouteTable *>
262  (vrf->GetInet4UnicastRouteTable());
263  InetUnicastAgentRouteTable *inet6_table =
264  static_cast<InetUnicastAgentRouteTable *>
265  (vrf->GetInet6UnicastRouteTable());
266  if (!inet4_table || !inet6_table)
267  continue;
268  WalkBridgeInetTables(inet4_table, inet6_table);
269  }
270  it++;
271  }
272 }
273 
275 (const VnEntry *vn) {
276  VnLrSetIter it = vn_lr_set_.find(vn);
277  if (it != vn_lr_set_.end()) {
278  return GetRoutingVrfUsingUuid(it->second);
279  }
280  return NULL;
281 }
282 
284 (const AgentRoute *rt) {
285  return GetRoutingVrfUsingUuid(GetLogicalRouterUuidUsingRoute(rt));
286 }
287 
289 (const boost::uuids::uuid &lr_uuid) {
290  LrVrfInfoMapIter it = lr_vrf_info_map_.find(lr_uuid);
291  if (it != lr_vrf_info_map_.end()) {
292  return it->second.routing_vrf_;
293  }
294  return NULL;
295 }
296 
298 (const AgentRoute *rt) {
299  using boost::uuids::nil_uuid;
300 
302  return rt->vrf()->vn()->logical_router_uuid();
303  }
304 
305  const VnEntry* rt_vn = rt->vrf()->vn();
306  if (!rt_vn) {
307  return nil_uuid();
308  }
309 
310  const VxlanRoutingVnState *vn_state =
311  dynamic_cast<const VxlanRoutingVnState *>(rt_vn->
312  GetAgentDBEntryState(mgr_->vn_listener_id()));
313  if ((vn_state == NULL) || (vn_state->vmi_list_.size() == 0)) {
314  return nil_uuid();
315  }
316 
317  return vn_state->logical_router_uuid_;
318 }
319 
320 // Invoked everytime when a vrf is pulled out of use.
321 // Holds on object till all bridge and routing vrf are gone.
323  if ((it->second.routing_vrf_ == NULL) &&
324  (it->second.bridge_vn_list_.size() == 0)) {
325  lr_vrf_info_map_.erase(it);
326  }
327 }
328 
331 
336  agent_(agent), walker_(), vn_listener_id_(),
337  vrf_listener_id_(), vmi_listener_id_(), vrf_mapper_(this) {
338  //routing_vrf_interface_peer_ = agent_->evpn_routing_peer();
341 }
342 
344 }
345 
347  // Walker to go through routes in bridge evpn tables.
348  walker_.reset(new VxlanRoutingRouteWalker("VxlanRoutingManager", this,
349  agent_));
351  RegisterWalker(static_cast<AgentRouteWalker *>(walker_.get()));
352 
353  // Register all listener ids.
356  this, _1, _2));
358  boost::bind(&VxlanRoutingManager::VrfNotify, this, _1, _2));
360  boost::bind(&VxlanRoutingManager::VmiNotify, this, _1, _2));
361 }
362 
368  ReleaseWalker(walker_.get());
369  walker_.reset(NULL);
370 }
371 
384  VnEntry *vn = dynamic_cast<VnEntry *>(e);
385  VxlanRoutingVnState *vn_state = dynamic_cast<VxlanRoutingVnState *>
387 
388  if (vn->IsDeleted() && vn_state != NULL) {
389  if (vn_state->is_routing_vn_) {
390  RoutingVnNotify(vn, vn_state);
391  } else {
392  BridgeVnNotify(vn, vn_state);
393  }
394 
395  //Delete State
396  vn->ClearState(partition->parent(), vn_listener_id_);
397  delete vn_state;
398  return;
399  }
400 
401  // if the VN had been deleted previously
402  if (!vn_state && vn->IsDeleted()) {
403  return;
404  }
405 
406  if (!vn_state) {
407  vn_state = new VxlanRoutingVnState(this);
408  vn->SetState(partition->parent(), vn_listener_id_, vn_state);
409  }
410 
411  if (vn->vxlan_routing_vn()) {
412  vn_state->is_routing_vn_ = vn->vxlan_routing_vn();
413  }
414 
415  vn_state->vrf_ref_ = vn->GetVrf();
416  if (vn_state->is_routing_vn_) {
417  vn_state->logical_router_uuid_ = vn->logical_router_uuid();
418  RoutingVnNotify(vn, vn_state);
419  } else {
420  BridgeVnNotify(vn, vn_state);
421  }
422 
423  return;
424 }
425 
427  VxlanRoutingVnState *vn_state) {
428  using boost::uuids::nil_uuid;
429 
430  if (vn_state->vmi_list_.size() == 0) {
431  vn_state->logical_router_uuid_ = nil_uuid();
432  }
433 
434  VxlanRoutingVnState::VmiListIter it = vn_state->vmi_list_.begin();
435  while (it != vn_state->vmi_list_.end()) {
436  vn_state->logical_router_uuid_ = (*it)->logical_router_uuid();
437  if ((*it)->logical_router_uuid() != nil_uuid()) {
438  return;
439  }
440  //Delete VMI with no lr uuid, vmi update will handle rest.
441  vn_state->vmi_list_.erase(it);
442  if (vn_state->vmi_list_.size() == 0) {
443  vn_state->logical_router_uuid_ = nil_uuid();
444  return;
445  }
446  it = vn_state->vmi_list_.begin();
447  }
448  return;
449 }
450 
452  VxlanRoutingVnState *vn_state) {
453  using boost::uuids::nil_uuid;
454 
455  if (vn->logical_router_uuid() != nil_uuid()) {
456  return;
457  }
458 
462  bool withdraw = false;
463  bool update = true;
464 
465  // Update lr uuid in case some vmi is deleted or added.
466  UpdateLogicalRouterUuid(vn, vn_state);
467  if (vn->IsDeleted() || (vn->GetVrf() == NULL)) {
468  withdraw = true;
469  update = false;
470  }
471 
472  if (it != vrf_mapper_.vn_lr_set_.end() &&
473  (it->second != vn_state->logical_router_uuid_) &&
474  (vn_state->logical_router_uuid_ != nil_uuid())) {
475  withdraw = true;
476  }
477 
478  if (vn_state->logical_router_uuid_ == nil_uuid()) {
479  withdraw = true;
480  update = false;
481  }
482 
483  if (it != vrf_mapper_.vn_lr_set_.end()) {
484  routing_info_it = vrf_mapper_.lr_vrf_info_map_.find(it->second);
485  }
486 
487  // Handles deletion case
488  if (withdraw) {
489  if (routing_info_it != vrf_mapper_.lr_vrf_info_map_.end()) {
491  routing_info_it->second.bridge_vn_list_.find(vn);
492  std::string vrf_name = "";
493  if (routing_info_it->second.bridge_vrf_names_list_.count(vn) == 1) {
494  vrf_name = routing_info_it->second.bridge_vrf_names_list_.at(vn);
495  DeleteSubnetRoute(vn, vrf_name);
496  }
497  if (br_it != routing_info_it->second.bridge_vn_list_.end()) {
498  vrf_mapper_.WalkRoutingVrf(it->second, vn, false, true);
499  routing_info_it->second.bridge_vn_list_.erase(br_it);
500  routing_info_it->second.bridge_vrf_names_list_.erase(vn);
501  }
502  // Trigger delete of logical router
503  vrf_mapper_.TryDeleteLogicalRouter(routing_info_it);
504  }
505  vrf_mapper_.vn_lr_set_.erase(vn);
506  }
507 
508  if (update) {
510  if (vrf_mapper_.vn_lr_set_[vn] == nil_uuid()) {
511  return;
512  }
513 
516  lr_vrf_info.bridge_vn_list_.insert(vn);
517  if (vn->GetVrf())
518  lr_vrf_info.bridge_vrf_names_list_[vn] = vn->GetVrf()->GetName();
519  vrf_mapper_.WalkRoutingVrf(vrf_mapper_.vn_lr_set_[vn], vn, true, false);
520  }
521 
522  // Without vrf walks cant be scheduled
523  if (!vn_state->vrf_ref_.get()) {
524  return;
525  }
526 
527  // Walk Evpn table if withdraw or update was done
528  if (update || withdraw) {
529  InetUnicastAgentRouteTable *inet4_table =
530  static_cast<InetUnicastAgentRouteTable *>(vn_state->vrf_ref_.get()->
531  GetInet4UnicastRouteTable());
532  InetUnicastAgentRouteTable *inet6_table =
533  static_cast<InetUnicastAgentRouteTable *>(vn_state->vrf_ref_.get()->
534  GetInet6UnicastRouteTable());
535  if (inet4_table && inet6_table) {
536  vrf_mapper_.WalkBridgeInetTables(inet4_table, inet6_table);
537  }
538  }
539  return;
540 }
541 
543  if (rt_vrf == NULL) {
544  return;
545  }
546  // Loop over all EVPN routes and delete them
547 
548  EvpnAgentRouteTable *evpn_table = dynamic_cast<EvpnAgentRouteTable *>
549  (rt_vrf->GetEvpnRouteTable());
550  if (evpn_table == NULL) {
551  return;
552  }
553  EvpnRouteEntry *c_entry = dynamic_cast<EvpnRouteEntry *>
554  (evpn_table->GetTablePartition(0)->GetFirst());
555 
556  const std::string vrf_name = rt_vrf->GetName();
557  const uint32_t ethernet_tag = 0;
558  const MacAddress mac_addr;
559  while (c_entry) {
560  const IpAddress prefix_ip = c_entry->prefix_address();
561  const uint32_t plen = c_entry->prefix_length();
562 
563  // Compute next entry in advance
564  if (c_entry && c_entry->get_table_partition())
565  c_entry = dynamic_cast<EvpnRouteEntry *>
566  (c_entry->get_table_partition()->GetNext(c_entry));
567  else
568  break;
569 
570  // Delete routes originated from bridge networks
572  vrf_name,
573  mac_addr,
574  prefix_ip,
575  plen,
576  ethernet_tag, // ethernet_tag = 0 for Type5
577  NULL);
578 
580  vrf_name, prefix_ip, plen, NULL);
581 
582  // Delete routes originated from BPG peers (EVPN Type5 table)
584  vrf_name,
585  mac_addr,
586  prefix_ip,
587  plen,
588  ethernet_tag, // ethernet_tag = 0 for Type5
589  NULL);
590 
592  vrf_name, prefix_ip, plen, NULL);
593  }
594 }
595 
597  VxlanRoutingVnState *vn_state) {
598 
599  bool withdraw = false;
600  bool update = false;
602 
603  if (vn->IsDeleted() ||
604  (vn->GetVrf() == NULL) ||
605  (vn_state->is_routing_vn_ == false)) {
606  update = false;
607  withdraw = true;
608  } else {
609  update = true;
610  if (it != vrf_mapper_.vn_lr_set_.end()) {
611  // LR uuid changed, so withdraw from old and add new.
612  if (it->second != vn_state->logical_router_uuid_) {
613  withdraw = true;
614  }
615  }
616  }
617 
618  if (withdraw && (it != vrf_mapper_.vn_lr_set_.end())) {
620  vrf_mapper_.lr_vrf_info_map_.find(it->second);
621  // Delete only if parent VN is same as notified VN coz it may so happen
622  // that some other VN has taken the ownership of this LR and
623  // notification of same came before this VN.
624  if (routing_info_it != vrf_mapper_.lr_vrf_info_map_.end()) {
625  if (routing_info_it->second.routing_vn_ == vn) {
627  // Routing VN/VRF
628  // Reset parent vn and routing vrf
629  routing_info_it->second.routing_vn_ = NULL;
630  routing_info_it->second.routing_vrf_ = NULL;
631  }
632  // Trigger delete of logical router
633  vrf_mapper_.TryDeleteLogicalRouter(routing_info_it);
634  }
635  vrf_mapper_.vn_lr_set_.erase(it);
636  }
637 
638  if (update) {
639  if (vn_state->logical_router_uuid_ == boost::uuids::nil_uuid()) {
640  return;
641  }
642 
643  if (it == vrf_mapper_.vn_lr_set_.end()) {
645  }
646 
647  VxlanRoutingVrfMapper::RoutedVrfInfo &routed_vrf_info =
649  // Take the ownership of LR
650  routed_vrf_info.routing_vn_ = vn;
651  if (routed_vrf_info.routing_vrf_ != vn->GetVrf()) {
652  routed_vrf_info.routing_vrf_ = vn->GetVrf();
653  vrf_mapper_.WalkBridgeVrfs(routed_vrf_info);
654  }
655  }
656 }
657 
663  DBEntryBase *e) {
664  VrfEntry *vrf = static_cast<VrfEntry *>(e);
665  if (vrf->GetName().compare(agent_->fabric_vrf_name()) == 0)
666  return;
667  if (vrf->GetName().compare(agent_->fabric_policy_vrf_name()) == 0)
668  return;
669 
670  VxlanRoutingState *state = dynamic_cast<VxlanRoutingState *>(vrf->
671  GetState(partition->parent(), vrf_listener_id_));
672  if (vrf->IsDeleted()) {
673  if (state) {
674  vrf->ClearState(partition->parent(), vrf_listener_id_);
675  delete state;
676  }
677  } else {
678  // Vrf was added/changed.
679  if (!state) {
680  state = new VxlanRoutingState(this, vrf);
681  vrf->SetState(partition->parent(), vrf_listener_id_, state);
682  }
683  if (vrf->vn() && vrf->vn()->vxlan_routing_vn()) {
684  vrf->set_routing_vrf(true);
685  }
686  }
687 }
688 
690  DBEntryBase *e) {
691  VmInterface *vmi = dynamic_cast<VmInterface *>(e);
692  if (!vmi) {
693  return;
694  }
695 
696  VnEntry *vn = vmi->GetNonConstVn();
697  VxlanRoutingVnState *vn_state = NULL;
698  VxlanRoutingVmiState *vmi_state = dynamic_cast<VxlanRoutingVmiState *>(vmi->
699  GetAgentDBEntryState(vmi_listener_id_));
700  if (vmi->IsDeleted() || (vn == NULL) ||
701  (vmi->logical_router_uuid() == boost::uuids::nil_uuid())) {
702  if (!vmi_state) {
703  return;
704  }
705  vn = vmi_state->vn_entry_.get();
706  vn_state = dynamic_cast<VxlanRoutingVnState *>
708  if (vn_state)
709  vn_state->DeleteVmi(vn, vmi);
710  vmi->ClearState(partition->parent(), vmi_listener_id_);
711  delete vmi_state;
712  return;
713  }
714 
715  if ((vmi->device_type() != VmInterface::VMI_ON_LR) ||
716  (vmi->vmi_type() != VmInterface::ROUTER)) {
717  return;
718  }
719 
720  if (vmi->logical_router_uuid() == boost::uuids::nil_uuid()) {
721  return;
722  }
723 
724  // Without VN no point of update
725  if (!vn) {
726  return;
727  }
728 
729  if (!vmi_state) {
730  vmi_state = new VxlanRoutingVmiState();
731  vmi->SetState(partition->parent(), vmi_listener_id_, vmi_state);
732  vmi_state->vn_entry_ = vn;
733  }
734  // Update logical_router_uuid
735  vmi_state->logical_router_uuid_ = vmi->logical_router_uuid();
736 
737  // Its necessary to add state on VN so as to push VMI. VN notify can come
738  // after VMI notify.
739  VnNotify(vn->get_table_partition(), vn);
740  // Now get VN state and add/delete VMI there
741  vn_state = dynamic_cast<VxlanRoutingVnState *>
743  if (vn_state) {
744  vn_state->AddVmi(vn, vmi);
745  }
746 }
747 
748 void VxlanRoutingManager::HandleSubnetRoute(const VrfEntry *vrf, bool bridge_vrf) {
749  //
750  // New version
751  //
752  if (vrf->vn() && vrf->vn()->vxlan_routing_vn() == false) {
753  const VrfEntry *routing_vrf =
755  if (!routing_vrf || vrf->IsDeleted()) {
756  DeleteSubnetRoute(vrf);
757  vrf->vn()->set_lr_vrf(NULL);
758  } else {
759  UpdateSubnetRoute(vrf, routing_vrf);
760  vrf->vn()->set_lr_vrf(routing_vrf);
761  }
762  }
763 }
764 
766  const std::string& vrf_name,
767  const IpAddress& ipam_prefix,
768  const uint32_t plen) {
769  if (vn == NULL || vrf_name == std::string(""))
770  return;
771 
773 
774  if (lr_it == vrf_mapper_.vn_lr_set_.end() ||
775  lr_it->second == boost::uuids::nil_uuid())
776  return;
777 
779  vrf_mapper_.lr_vrf_info_map_[lr_it->second];
780 
781  if (lr_vrf_info.bridge_vn_list_.size() == 0)
782  return;
783 
785  lr_vrf_info.bridge_vn_list_.begin();
786  while (it != lr_vrf_info.bridge_vn_list_.end()) {
787  if (vn == *it) {
788  it++;
789  continue;
790  }
791 
792  (*it)->GetVrf()->GetInetUnicastRouteTable(ipam_prefix)->
793  Delete(agent_->evpn_routing_peer(), (*it)->GetVrf()->GetName(),
794  ipam_prefix, plen, NULL);
795  it++;
796  }
797 }
798 
799 void VxlanRoutingManager::DeleteSubnetRoute(const VnEntry *vn, const std::string& vrf_name) {
800  if (vn == NULL || vrf_name == std::string(""))
801  return;
802  std::vector<VnIpam> bridge_vn_ipam = vn->GetVnIpam();
803 
804  if (bridge_vn_ipam.size() == 0)
805  return;
806 
808 
809  if (lr_it == vrf_mapper_.vn_lr_set_.end() ||
810  lr_it->second == boost::uuids::nil_uuid())
811  return;
812 
814  vrf_mapper_.lr_vrf_info_map_[lr_it->second];
815 
816  if (lr_vrf_info.bridge_vn_list_.size() == 0)
817  return;
818 
820  lr_vrf_info.bridge_vn_list_.begin();
821  while (it != lr_vrf_info.bridge_vn_list_.end()) {
822  if (vn == *it) {
823  it++;
824  continue;
825  }
826 
827  for (std::vector<VnIpam>::iterator ipam_itr = bridge_vn_ipam.begin();
828  ipam_itr < bridge_vn_ipam.end(); ipam_itr++) {
829  (*it)->GetVrf()->GetInetUnicastRouteTable(ipam_itr->ip_prefix)->
830  Delete(agent_->evpn_routing_peer(), (*it)->GetVrf()->GetName(),
831  ipam_itr->GetSubnetAddress(), ipam_itr->plen, NULL);
832  }
833  std::vector<VnIpam> vn_ipam = (*it)->GetVnIpam();
834 
835  if (vn_ipam.size() == 0) {
836  it++;
837  continue;
838  }
839  for (std::vector<VnIpam>::iterator vn_ipam_itr = vn_ipam.begin();
840  vn_ipam_itr < vn_ipam.end(); vn_ipam_itr++) {
842  vrf_name, vn_ipam_itr->GetSubnetAddress(),
843  vn_ipam_itr->plen, NULL);
844  }
845  it++;
846  }
847 }
848 
849 //void VxlanRoutingManager::DeleteSubnetRoute(const VrfEntry *vrf, VnIpam *ipam) {
851  if (vrf == NULL)
852  return;
853  DeleteSubnetRoute(vrf->vn(), vrf->GetName());
854 }
855 
857  const VrfEntry *routing_vrf) {
858  if (!bridge_vrf->vn())
859  return;
860 
861  std::vector<VnIpam> bridge_vn_ipam = bridge_vrf->vn()->GetVnIpam();
862 
863  if (bridge_vn_ipam.size() == 0)
864  return;
865 
867  vrf_mapper_.vn_lr_set_.find(bridge_vrf->vn());
868 
869  if (lr_it == vrf_mapper_.vn_lr_set_.end() ||
870  lr_it->second == boost::uuids::nil_uuid())
871  return;
872 
874  vrf_mapper_.lr_vrf_info_map_[lr_it->second];
875 
876  if (lr_vrf_info.bridge_vn_list_.size() == 0)
877  return;
878 
880  lr_vrf_info.bridge_vn_list_.begin();
881  while (it != lr_vrf_info.bridge_vn_list_.end()) {
882  if (bridge_vrf->vn() == *it) {
883  it++;
884  continue;
885  }
886 
887  for (std::vector<VnIpam>::iterator ipam_itr = bridge_vn_ipam.begin();
888  ipam_itr < bridge_vn_ipam.end(); ipam_itr++) {
890  nh_req.key.reset(new VrfNHKey(routing_vrf->GetName(), false, false));
891  nh_req.data.reset(new VrfNHData(false, false, false));
892  (*it)->GetVrf()->GetInetUnicastRouteTable(ipam_itr->ip_prefix)->
893  AddEvpnRoutingRoute(ipam_itr->ip_prefix, ipam_itr->plen, routing_vrf,
896  CommunityList(),
897  PathPreference(),
898  EcmpLoadBalance(),
899  TagList(),
900  nh_req,
901  routing_vrf->vxlan_id(),
902  VnListType());
903  }
904 
905  std::vector<VnIpam> vn_ipam = (*it)->GetVnIpam();
906  for (std::vector<VnIpam>::iterator vn_ipam_itr = vn_ipam.begin();
907  vn_ipam_itr != vn_ipam.end(); vn_ipam_itr++) {
908 
910  nh_req.key.reset(new VrfNHKey(routing_vrf->GetName(), false, false));
911  nh_req.data.reset(new VrfNHData(false, false, false));
912  bridge_vrf->GetInetUnicastRouteTable(vn_ipam_itr->ip_prefix)->
913  AddEvpnRoutingRoute(vn_ipam_itr->ip_prefix, vn_ipam_itr->plen, routing_vrf,
916  CommunityList(),
917  PathPreference(),
918  EcmpLoadBalance(),
919  TagList(),
920  nh_req,
921  routing_vrf->vxlan_id(),
922  VnListType());
923  }
924  it++;
925  }
926 }
927 
931 void VxlanRoutingManager::FillSandeshInfo(VxlanRoutingResp *resp) {
934  std::vector<VxlanRoutingMap> vr_map;
935  while (it1 != vrf_mapper_.lr_vrf_info_map_.end()) {
936  VxlanRoutingMap vxlan_routing_map;
937  vxlan_routing_map.set_logical_router_uuid(UuidToString(it1->first));
938  vxlan_routing_map.set_routing_vrf(it1->second.routing_vrf_->
939  GetName());
940  vxlan_routing_map.set_parent_routing_vn(it1->second.routing_vn_->
941  GetName());
943  it1->second.bridge_vn_list_.begin();
944  while (it2 != it1->second.bridge_vn_list_.end()) {
945  VxlanRoutingBridgeVrf bridge_vrf;
946  if ((*it2)->GetVrf()) {
947  bridge_vrf.set_bridge_vrf((*it2)->GetVrf()->GetName());
948  }
949  bridge_vrf.set_bridge_vn((*it2)->GetName());
950  vxlan_routing_map.bridge_vrfs.push_back(bridge_vrf);
951  it2++;
952  }
953  vr_map.push_back(vxlan_routing_map);
954  it1++;
955  }
956  resp->set_vr_map(vr_map);
957 }
958 
959 void VxlanRoutingReq::HandleRequest() const {
960  VxlanRoutingResp *resp = new VxlanRoutingResp();
961  Agent *agent = Agent::GetInstance();
962  VxlanRoutingManager *vxlan_routing_mgr =
963  agent->oper_db()->vxlan_routing_manager();
964  if (vxlan_routing_mgr) {
965  resp->set_context(context());
966  vxlan_routing_mgr->FillSandeshInfo(resp);
967  }
968  resp->set_more(false);
969  resp->Response();
970  return;
971 }
const std::string & GetName() const
Definition: peer.h:86
void AddVmi(const VnEntry *vn, const VmInterface *vmi)
Adds a VmInterface (LR port) to a Logical Router and connects the given VirtualNetwork (to which the ...
void VrfNotify(DBTablePartBase *partition, DBEntryBase *e)
A handler for changes (new/update/delete) in a VRF instance (VrfEntry class).
VnEntry * GetNonConstVn() const
virtual ~VxlanRoutingManager()
Destroys the VxlanRoutingManager instance.
const Peer * local_vm_export_peer() const
Definition: agent.h:1040
static Agent * GetInstance()
Definition: agent.h:436
VxlanRoutingVnState(VxlanRoutingManager *mgr)
Constructs new instance using VxlanRoutingManager.
virtual DBEntryBase * GetFirst()=0
Definition: vrf.h:86
AgentRouteTable * GetEvpnRouteTable() const
Definition: vrf.cc:330
VxlanRoutingVmiState()
Constructs new instance of VxlanRoutingVmiState.
DBTable::ListenerId vrf_listener_id_
An ID of the listener to changes in VrfTable.
std::set< const VmInterface * > vmi_list_
A list of VmInterface (router&#39;s ports) connected to a Logical Router (LR)
LrVrfInfoMap::iterator LrVrfInfoMapIter
A typedef for iterator of LrVrfInfoMap.
void set_lr_vrf(const VrfEntry *vrf)
Definition: vn.h:265
BridgeVnList bridge_vn_list_
The list of bridge virtual networks (VirtualNetwork) connected to a LR.
void RoutingVrfRouteWalkDone(DBTable::DBTableWalkRef walk_ref, DBTableBase *partition)
Handles completion of route walk in the EVPN table of a routing VRF instance.
VmInterface::DeviceType device_type() const
bool IsDeleted() const
Definition: db_entry.h:49
VxlanRoutingRouteWalker(const std::string &name, VxlanRoutingManager *mgr, Agent *agent)
Constructs a new instance using the given name, pointer to the VxlanRoutingManager and pointer to the...
void SetState(DBTableBase *tbl_base, ListenerId listener, DBState *state)
Definition: db_entry.cc:22
void DeleteVmi(const VnEntry *vn, const VmInterface *vmi)
Deletes the VmInterface from set of connected interfaces and disconnects the given VirtualNetwork fro...
boost::asio::ip::address IpAddress
Definition: address.h:13
static void DeleteReq(const Peer *peer, const std::string &vrf_name, const MacAddress &mac, const IpAddress &ip_addr, uint32_t plen, uint32_t ethernet_tag, AgentRouteData *data)
const Peer * vxlan_bgp_peer() const
Definition: agent.h:1028
std::vector< int > SecurityGroupList
Definition: agent.h:201
std::unique_ptr< DBRequestData > data
Definition: db_table.h:49
InetUnicastAgentRouteTable * GetInet4UnicastRouteTable() const
Definition: vrf.cc:319
void HandleSubnetRoute(const VrfEntry *vrf, bool bridge_vrf=false)
Handles routing routes (with VrfNH) update in the routing VRF instance.
DBTableBase * parent()
bool WithdrawEvpnRouteFromRoutingVrf(const VrfEntry *routing_vrf, DBTablePartBase *partition, DBEntryBase *e)
Deletes a given EVPN route from EVPN table of the routing VRF instance.
const boost::uuids::uuid GetLogicalRouterUuidUsingRoute(const AgentRoute *rt)
Find the UUID of the LR using a given route (AgentRoute).
InterfaceTable * interface_table() const
Definition: agent.h:465
boost::uuids::uuid uuid
VnTable * vn_table() const
Definition: agent.h:495
virtual DBEntryBase * GetNext(const DBEntryBase *)=0
const VrfEntry * GetRoutingVrfUsingAgentRoute(const AgentRoute *rt)
Find the routing VRF instance using a given route (AgentRoute).
InetUnicastAgentRouteTable * GetInet6UnicastRouteTable() const
Definition: vrf.cc:338
const string & GetName() const
Definition: vrf.h:100
static std::string UuidToString(const boost::uuids::uuid &id)
Definition: string_util.h:138
InetTableWalker inet6_table_walker_
The set of walkers for Inet IPv6 tables of bridge VRF instances.
const VrfEntry * GetRoutingVrfUsingUuid(const boost::uuids::uuid &lr_uuid)
Find the routing VRF instance using a given LR UUID.
const boost::uuids::uuid & logical_router_uuid() const
Definition: interface.h:146
VxlanRoutingManager * vxlan_routing_manager() const
Definition: operdb_init.h:98
Base class for all Route entries in agent.
Definition: agent_route.h:224
const VrfEntry * GetRoutingVrfUsingVn(const VnEntry *vn)
Find the routing VRF instance using a given virtual network.
void UpdateSubnetRoute(const VrfEntry *vrf, const VrfEntry *routing_vrf)
Updates subnet routes (actually, paths with VrfNH) in the given bridge VRF.
VrfEntryRef vrf_ref_
Holds a reference to a VrfEntry when VirtualNetwork&#39;s reference stored in VrfGet() is null...
void Unregister(ListenerId listener)
Definition: db_table.cc:186
const VnEntry * routing_vn_
A pointer to the routing virtual network (VirtualNetwork) connected to a LR.
OperDB * oper_db() const
Definition: agent.cc:1013
const VrfEntry * routing_vrf_
A pointer to the routing VRF instance (L3 VRF) connected to a LR.
VnEntryRef vn_entry_
Reference (smart pointer) to the virtual network (VirtualNetwork) to which VmInterface belongs to...
VxlanRoutingManager * mgr_
A pointer to the VxlanRoutingManager instance.
DBTable::ListenerId vmi_listener_id_
An ID of the listener to changes in InterfaceTable.
DBState * GetAgentDBEntryState(int listener_id)
Definition: agent_db.cc:31
ListenerId Register(ChangeCallback callback, const std::string &name="unspecified")
Definition: db_table.cc:181
const std::string & fabric_vrf_name() const
Definition: agent.h:903
This class manages routes leaking between bridge VRF instances and the routing VRF instance...
void WalkAgain(DBTableWalkRef walk)
Definition: db_table.cc:631
VrfEntry * vrf_entry() const
Definition: agent_route.cc:459
Agent * agent_
A pointer to the Agent instance.
VxlanRoutingManager * mgr_
A pointer to the instance of VxlanRoutingManager.
static bool IsRoutingVrf(const VrfEntry *vrf)
Determines whether the pointer to the VRF instance is of routing type.
VnLrSet vn_lr_set_
The map between pointer to VirtualNetwork (a bridge or routing virtual network connected to some LR) ...
VmiList::iterator VmiListIter
A typedef for the iterator of VxlanRoutingVnState::VmiList.
virtual ~VxlanRoutingRouteWalker()
Destructs an instance of VxlanRoutingRouteWalker.
Definition: agent.h:358
AgentRouteWalkerManager * agent_route_walk_manager() const
Definition: operdb_init.h:91
virtual bool RouteWalkNotify(DBTablePartBase *partition, DBEntryBase *e)
Runs route leaking process when L3 VRF instance is added/deleted or when a bridge VRF is attached / d...
bool RouteNotify(DBTablePartBase *partition, DBEntryBase *e)
Handler for changes (new/update/delete) in a route (EVPN or Inet). Main entry point for routes leakin...
InetUnicastAgentRouteTable * GetInetUnicastRouteTable(const IpAddress &addr) const
Definition: vrf.cc:575
std::unique_ptr< DBRequestKey > key
Definition: db_table.h:48
bool vxlan_routing_vn() const
Definition: vn.h:255
void WalkRoutingVrf(const boost::uuids::uuid &lr_uuid, const VnEntry *vn, bool update, bool withdraw)
Walks the EVPN table of the routing VRF instance of a given LR.
virtual ~VxlanRoutingVmiState()
Destroys an instance of VxlanRoutingVmiState.
void VnNotify(DBTablePartBase *partition, DBEntryBase *e)
A handler for changes (new/update/delete) in a virtual network (VnEntry class).
virtual ~VxlanRoutingState()
Destroys an instance.
boost::uuids::uuid logical_router_uuid_
UUID of the LR to which this VmInterface is connected.
const std::vector< VnIpam > & GetVnIpam() const
Definition: vn.h:171
boost::uuids::uuid logical_router_uuid() const
Returns the UUID of the Logical Router.
const std::string & name() const
Definition: db_table.h:110
std::vector< std::string > CommunityList
Definition: bgp_config.h:347
void FillSandeshInfo(VxlanRoutingResp *resp)
Updates Sandesh response.
void Register()
Registers handlers for events associated with changes in virtual networks (VnTable class) and VRF ins...
Definition: peer.h:44
std::set< std::string > VnListType
Definition: agent.h:212
static void DeleteReq(const Peer *peer, const string &vrf_name, const IpAddress &addr, uint8_t plen, AgentRouteData *data)
void ClearState(DBTableBase *tbl_base, ListenerId listener)
Definition: db_entry.cc:73
void BridgeInet6RouteWalkDone(DBTable::DBTableWalkRef walk_ref, DBTableBase *partition)
Handles completion of route walk in an Inet IPv6 table of a bridge VRF instance.
Tracks movement of a VmInterface amongth LRs. This is used to associate VmInterface with a LR and a V...
virtual const PrefixType & prefix_address() const
Returns the value of a stored prefix address (IPv4, IPv6 or MAC address)
Definition: agent_route.h:375
Definition: vn.h:151
VxlanRoutingManager(Agent *agent)
Constructs instance of the class and links to the Agent class instance. Since only one agent class in...
VrfTable * vrf_table() const
Definition: agent.h:485
virtual DBTablePartBase * GetTablePartition(const DBRequestKey *key)
Definition: db_table.cc:436
void WalkBridgeInetTables(InetUnicastAgentRouteTable *inet4, InetUnicastAgentRouteTable *inet6)
Walks given Inet tables (IPv4 and IPv6).
void TryDeleteLogicalRouter(LrVrfInfoMapIter &it)
Attempts to delete the given LR.
BridgeVrfNamesList bridge_vrf_names_list_
The list of bridge virtual networks (VirtualNetwork) names connected to a LR.
const boost::uuids::uuid & logical_router_uuid() const
Definition: vn.h:256
VrfEntry * GetVrf() const
Definition: vn.h:170
uint8_t prefix_length() const
!
void BridgeInet4RouteWalkDone(DBTable::DBTableWalkRef walk_ref, DBTableBase *partition)
Handles completion of route walk in the Inet IPv4 table of a bridge VRF instance. ...
VmInterface::VmiType vmi_type() const
uint32_t vxlan_id() const
Definition: vrf.h:165
VxlanRoutingVrfMapper vrf_mapper_
A map between LR uuids and associated bridge and routing VRF instances.
void UpdateLogicalRouterUuid(const VnEntry *vn, VxlanRoutingVnState *vn_state)
VnEntry * vn() const
Definition: vrf.h:101
#define LOG(_Level, _Msg)
Definition: logging.h:33
VrfEntry * vrf() const
Definition: agent_route.h:275
bool InetRouteNotify(DBTablePartBase *partition, DBEntryBase *e)
Routes leaking functions.
This state tracks all virtual machine interfaces (VmInterface) attached to a Logical Router (LR)...
The structure holds information about virtual networks connected to a logical router (LR) ...
VxlanRoutingVrfMapper(VxlanRoutingManager *mgr)
Constructs a new instance of VxlanRoutingVrfMapper using the given pointer to VxlanRoutingManager.
This state tracks inet and evpn table listeners. The state establishes link between Inet tables of a ...
void Shutdown()
Unregisters handlers for events associated with changes in virtual networks (VnTable class) and VRF i...
bool routing_vrf_
Definition: vrf.h:260
DBTablePartBase * get_table_partition() const
Definition: db_entry.cc:115
virtual ~VxlanRoutingVrfMapper()
Destroys an instance of VxlanRoutingVrfMapper().
boost::intrusive_ptr< DBTableWalk > DBTableWalkRef
Definition: db_table.h:169
BridgeVnList::iterator BridgeVnListIter
A type for iterator of the list of bridge virtual networks connected to a LR.
void DeleteIpamRoutes(const VnEntry *vn, const std::string &vrf_name, const IpAddress &ipam_prefix, const uint32_t plen)
Delete routes to IPAM, specified by IP prefix and prefix length.
LrVrfInfoMap lr_vrf_info_map_
The map between Logical router UUID and RoutedVrfInfo.
void VmiNotify(DBTablePartBase *partition, DBEntryBase *e)
Handler for changes (new/update/delete) in a VMI (VmInterface class).
InetTableWalker inet4_table_walker_
The set of walkers for Inet IPv4 tables of bridge VRF instances.
bool is_routing_vn_
Returns true when state is associated with a routing VirtualNetwork.
static const Peer * routing_vrf_interface_peer_
Internal data of this class.
void RoutingVrfDeleteAllRoutes(VrfEntry *rt_vrf)
deletes all routes in EVPN table of routing VRF
void DeleteSubnetRoute(const VrfEntry *vrf)
Deletes subnet routes (actually, paths with VrfNH) in the given bridge VRF. This function is demanded...
friend class VxlanRoutingRouteWalker
Friends declarations.
VxlanRoutingManager * mgr_
A pointer to the VxlanRoutingManager instance.
bool LeakRoutesIntoBridgeTables(DBTablePartBase *partition, DBEntryBase *e, const boost::uuids::uuid &uuid, const VnEntry *vn, bool update=false)
Performs advertisement and deletion of routing routes (with VrfNH) in bridge VRF instances. External tunnels and routes with a prefix that is not present in bridge VRF instance are selected for leaking.
AgentRouteWalkerPtr walker_
A pointer to the walker to loop over INET tables in bridge VRF instances.
virtual ~VxlanRoutingVnState()
Destroys a VxlanRoutingVnState object.
void RoutingVnNotify(const VnEntry *vn, VxlanRoutingVnState *vn_state)
A handler for changes (new/update/delete) in the virtual network from a routing VRF.
static const Peer * routing_vrf_vxlan_bgp_peer_
A pointer to the Peer where all BGP routes are stored.
DBTable::ListenerId vn_listener_id_
An ID of the listener to changes in VnTable.
void BridgeVnNotify(const VnEntry *vn, VxlanRoutingVnState *vn_state)
A handler for changes (new/update/delete) in the virtual network from a bridge VRF.
void WalkBridgeVrfs(const RoutedVrfInfo &routing_vrf_info)
Walks Inet tables of all bridge VRF instances connected to a LR (given in routing_vrf_info parameter)...
boost::uuids::uuid logical_router_uuid_
A UUID of the Logical Router.
void set_routing_vrf(bool val)
Definition: vrf.h:222
const Peer * evpn_routing_peer() const
Definition: agent.h:1027
std::vector< int > TagList
Definition: agent.h:202
VnLrSet::iterator VnLrSetIter
A typedef for iterator of VnLrSet.
VxlanRoutingState(VxlanRoutingManager *mgr, VrfEntry *vrf)
Construct new instance using the given VxlanRoutingManager and VRF instance (VrfEntry).
const std::string & fabric_policy_vrf_name() const
Definition: agent.h:908