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