OpenSDN source code
vxlan_auxilliary.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 <oper/route_common.h>
10 #include <xmpp_enet_types.h>
11 #include <xmpp_unicast_types.h>
12 #include <oper/tunnel_nh.h>
14 #include <oper/bgp_as_service.h>
15 
16 
17 static void AdvertiseLocalRoute(const IpAddress &prefix_ip,
18  const uint32_t plen,
19  DBRequest &nh_req,
20  const Peer *peer,
21  const RouteParameters& params,
22  EvpnAgentRouteTable *evpn_table);
23 
24 static bool IsGivenTypeCompositeNextHop(const NextHop *nh,
25  NextHop::Type nh_type, bool strict_match = true) {
26  if (nh->GetType() != NextHop::COMPOSITE) {
27  return false;
28  }
29  const CompositeNH *composite_nh =
30  dynamic_cast<const CompositeNH*>(nh);
31  uint32_t comp_nh_count = composite_nh->ComponentNHCount();
32  for (uint32_t i=0; i < comp_nh_count; i++) {
33  const NextHop * c_nh = composite_nh->GetNH(i);
34  if (c_nh != NULL) {
35  // return true if at least one componet is interface
36  if (c_nh->GetType() == nh_type &&
37  !strict_match) {
38  return true;
39  }
40  // return true only if all components are interfaces
41  if (c_nh->GetType() != nh_type &&
42  strict_match) {
43  return false;
44  }
45  }
46  }
47  return strict_match;
48 }
49 
50 //
51 // VxlanRoutingManager members
52 //
53 
55  const NextHop *path_nh = path->nexthop();
56  if (path_nh->GetType() != NextHop::COMPOSITE) {
57  return 0;
58  }
59  loc_sequence_++;
60  return loc_sequence_;
61 }
62 
63 bool VxlanRoutingManager::is_ipv4_string(const std::string& prefix_str) {
64  return (prefix_str.find(".") != std::string::npos);
65 }
66 
67 bool VxlanRoutingManager::is_ipv6_string(const std::string& prefix_str) {
68  return (prefix_str.find(":") != std::string::npos) &&
69  !is_ipv4_string(prefix_str);
70 }
71 
72 uint32_t VxlanRoutingManager::ipv4_prefix_len(const std::string& prefix_str) {
73  const std::string::size_type slash_pos = prefix_str.rfind("/");
74  if (slash_pos == std::string::npos) {
75  return 32;
76  }
77  const std::string len_str = prefix_str.substr(slash_pos + 1);
78  uint32_t prefix_len = 0;
79  std::istringstream(len_str) >> prefix_len;
80  return std::min(uint32_t(32), prefix_len);
81 }
82 
83 std::string VxlanRoutingManager::ipv4_prefix(const std::string& prefix_str) {
84  std::string::size_type first_dot_pos = 0;
85  std::string::size_type last_colon_pos =
86  prefix_str.rfind(":");
87  std::string::size_type slash_pos = prefix_str.rfind("/");
88  std::string ip_str = "0.0.0.0";
89  if ((first_dot_pos = prefix_str.find(".")) != std::string::npos) {
90  if (first_dot_pos - last_colon_pos >= 2 &&
91  first_dot_pos - last_colon_pos <= 4) {
92  ip_str = prefix_str.substr(last_colon_pos + 1);
93  }
94  if (last_colon_pos == string::npos) {
95  ip_str = prefix_str;
96  }
97  if (slash_pos != string::npos) {
98  ip_str = ip_str.substr(0, slash_pos);
99  }
100  }
101  return ip_str;
102 }
103 
104 uint32_t VxlanRoutingManager::ipv6_prefix_len(const std::string& prefix_str) {
105  const std::string::size_type slash_pos = prefix_str.rfind("/");
106  if (slash_pos == std::string::npos) {
107  return 128;
108  }
109  const std::string len_str = prefix_str.substr(slash_pos + 1);
110  uint32_t prefix_len = 0;
111  std::istringstream(len_str) >> prefix_len;
112  return std::min(uint32_t(128), prefix_len);
113 }
114 
115 std::string VxlanRoutingManager::ipv6_prefix(const std::string& prefix_str) {
116  const std::string zero_mac_str = "00:00:00:00:00:00";
117  const std::string::size_type mac_pos = prefix_str.find(zero_mac_str);
118  std::string ip_str = prefix_str;
119 
120  if (mac_pos != std::string::npos) {
121  ip_str = prefix_str.substr(mac_pos + zero_mac_str.size() + 1);
122  }
123 
124  const std::string::size_type slash_pos = ip_str.rfind("/");
125  if (slash_pos != std::string::npos) {
126  ip_str = ip_str.substr(0, slash_pos);
127  }
128  if (ip_str.find(":") == std::string::npos) {
129  ip_str = "::";
130  }
131  return ip_str;
132 }
133 
135  VxlanRoutingManager *vxlan_rt_mgr = NULL;
136  if (agent->oper_db()) {
137  vxlan_rt_mgr = agent->oper_db()->vxlan_routing_manager();
138  }
139  if (vxlan_rt_mgr == NULL) {
140  return false;
141  }
142  return true;
143 }
144 
145 std::string VxlanRoutingManager::GetOriginVn(const VrfEntry *routing_vrf,
146  const IpAddress& ip_addr,
147  const uint8_t& plen) {
148 
149  std::string origin_vn = "";
150  if (routing_vrf->vn()) {
153  [routing_vrf->vn()->logical_router_uuid()];
154  for (auto bridge_vn_entry : lr_vrf_info.bridge_vn_list_) {
155  VrfEntry* it_vrf = VnVrf(bridge_vn_entry, lr_vrf_info.bridge_vrf_names_list_[bridge_vn_entry]);
156  if (it_vrf == nullptr) {
157  continue;
158  }
159  InetUnicastRouteEntry *rt = it_vrf->GetUcRoute(ip_addr);
160  if (rt && RoutePrefixIsEqualTo(rt, ip_addr, plen)) {
161  origin_vn = bridge_vn_entry->GetName();
162  break;
163  }
164  }
165  }
166 
167  return origin_vn;
168 }
169 
171  const IpAddress& prefix_ip,
172  const uint32_t prefix_len) {
173  if (route == NULL ||
174  route->prefix_address() != prefix_ip ||
175  route->prefix_length() != prefix_len) {
176  return false;
177  }
178  return true;
179 }
180 
182  const IpAddress& prefix_ip,
183  const uint32_t prefix_len) {
184  if (route == NULL ||
185  route->prefix_address() != prefix_ip ||
186  route->prefix_length() != prefix_len) {
187  return false;
188  }
189  return true;
190 }
191 
192 bool VxlanRoutingManager::IsHostRoute(const IpAddress& prefix_ip, uint32_t prefix_len) {
193  if (prefix_ip.is_v4() && prefix_len == 32)
194  return true;
195  if (prefix_ip.is_v6() && prefix_len == 128)
196  return true;
197  return false;
198 }
199 
201  if (evpn_rt != NULL) {
202  return IsHostRoute(evpn_rt->prefix_address(), evpn_rt->prefix_length());
203  }
204  return false;
205 }
206 
208  if(rt->vrf() == NULL || rt->vrf()->vn() == NULL){
209  LOG(ERROR, "Error in VxlanRoutingManager::IsHostRouteFromLocalSubnet"
210  << ", vrf == NULL || vrf()->vn() == NULL");
211  assert(rt->vrf() && rt->vrf()->vn());
212  }
213 
214  if (IsHostRoute(rt) == false) {
215  return false;
216  }
217 
218  const boost::uuids::uuid lr_uuid =
220  if (lr_uuid == boost::uuids::nil_uuid()) {
221  return false;
222  }
223 
224  const VxlanRoutingVrfMapper::RoutedVrfInfo& vr_info =
225  vrf_mapper_.lr_vrf_info_map_[lr_uuid];
227  vr_info.bridge_vn_list_;
228 
229  const VnEntry *bridge_vn = NULL;
231  bridge_vns.begin();
232  while (it_br != bridge_vns.end()) {
233  bridge_vn = *it_br;
234  const std::vector<VnIpam> &VnIpams = bridge_vn->GetVnIpam();
235  for (uint32_t j=0; j < VnIpams.size(); j++) {
236  if (VnIpams[j].IsSubnetMember(rt->prefix_address())) {
237  return true;
238  }
239  }
240  it_br++;
241  }
242  return false;
243 }
244 
246  VrfEntry *bridge_vrf) {
247  // check that the Inet table holds the corresponding route
248  InetUnicastRouteEntry local_vm_route_key(
249  bridge_vrf,
250  routing_evpn_rt->prefix_address(),
251  routing_evpn_rt->prefix_length(), false);
252 
253  InetUnicastAgentRouteTable *inet_table =
254  bridge_vrf->GetInetUnicastRouteTable(routing_evpn_rt->prefix_address());
255  InetUnicastRouteEntry *inet_rt =
256  dynamic_cast<InetUnicastRouteEntry *>
257  (inet_table->FindLPM(local_vm_route_key));
258  if (inet_rt && RoutePrefixIsEqualTo(inet_rt, routing_evpn_rt->prefix_address(),
259  routing_evpn_rt->prefix_length())) {
260  return inet_rt->FindPath(agent_->evpn_routing_peer()) ? false : true;
261  }
262  return false;
263 }
264 
266  const Route::PathList & path_list = rt->GetPathList();
267  for (Route::PathList::const_iterator it = path_list.begin();
268  it != path_list.end(); ++it) {
269  const AgentPath* path =
270  dynamic_cast<const AgentPath*>(it.operator->());
271 
272  if (path != NULL &&
273  path->nexthop() != NULL &&
274  path->nexthop()->GetType() == NextHop::VRF) {
275  return true;
276  }
277  }
278  return false;
279 }
280 
282  const Route::PathList & path_list = evpn_rt->GetPathList();
283  for (Route::PathList::const_iterator it = path_list.begin();
284  it != path_list.end(); ++it) {
285  const AgentPath* path =
286  dynamic_cast<const AgentPath*>(it.operator->());
287  if (path != NULL &&
288  path->peer() != NULL &&
289  path->peer()->GetType() == Peer::BGP_PEER) {
290  return true;
291  }
292  }
293  return false;
294 }
295 
297  return vrf && vrf->vn() &&
298  vrf->vn()->vxlan_routing_vn();
299  // An alternative method
300  // if (vrf == NULL) {
301  // return false;
302  // }
303  // if (vrf->vn() == NULL) {
304  // return false;
305  // }
306  // if (vrf_mapper_.lr_vrf_info_map_.count(
307  // vrf->vn()->logical_router_uuid())) {
308  // const VxlanRoutingVrfMapper::RoutedVrfInfo &lr_vrf_info =
309  // vrf_mapper_.lr_vrf_info_map_.at(vrf->vn()->logical_router_uuid());
310  // if (lr_vrf_info.routing_vrf_ == vrf) {
311  // return true;
312  // }
313  // }
314  // return false;
315 }
316 
318  return vrf && vrf->vn() &&
319  !vrf->vn()->vxlan_routing_vn();
320 }
321 
322 
323 bool VxlanRoutingManager::IsRoutingVrf(const std::string vrf_name,
324  const Agent* agent) {
325  VxlanRoutingManager *vxlan_rt_mgr = NULL;
326  const VrfEntry *vrf_cand = NULL;
327  if (agent->oper_db()) {
328  vxlan_rt_mgr = agent->oper_db()->vxlan_routing_manager();
329  }
330  if (vxlan_rt_mgr == NULL) {
331  return false;
332  }
333  if (agent->vrf_table())
334  vrf_cand = agent->vrf_table()->FindVrfFromName(vrf_name);
335  if (vrf_cand == NULL) {
336  return false;
337  }
338  return vxlan_rt_mgr->IsRoutingVrf(vrf_cand);
339 }
340 
342  const AgentRoute *inet_rt,
343  const Peer::Type peer_type) {
344  if (inet_rt == NULL)
345  return NULL;
346 
347  const Route::PathList & path_list = inet_rt->GetPathList();
348  for (Route::PathList::const_iterator it = path_list.begin();
349  it != path_list.end(); ++it) {
350  const AgentPath* path =
351  dynamic_cast<const AgentPath*>(it.operator->());
352 
353  if (path != NULL &&
354  path->peer()->GetType() == peer_type) {
355  return path;
356  }
357  }
358  return NULL;
359 }
360 
362  const AgentRoute *route,
363  const Peer::Type peer_type,
364  const NextHop::Type nh_type,
365  bool strict_match) {
366  if (route == NULL)
367  return NULL;
368 
369  const Route::PathList & path_list = route->GetPathList();
370  for (Route::PathList::const_iterator it = path_list.begin();
371  it != path_list.end(); ++it) {
372  const AgentPath* path =
373  dynamic_cast<const AgentPath*>(it.operator->());
374 
375  if (path != NULL &&
376  path->nexthop() != NULL &&
377  path->peer() != NULL &&
378  path->peer()->GetType() == peer_type) {
379  if (path->nexthop()->GetType() == nh_type) {
380  return path;
381  }
382  if (IsGivenTypeCompositeNextHop(path->nexthop(), nh_type,
383  strict_match)) {
384  return path;
385  }
386  }
387  }
388  return NULL;
389 }
390 
392  const AgentRoute *inet_rt,
393  const Peer::Type peer_type,
394  bool strict_match) {
395  return FindPathWithGivenPeerAndNexthop(inet_rt,
396  peer_type, NextHop::INTERFACE, strict_match);
397 }
398 
400  const AgentRoute *inet_rt,
401  bool strict_match) {
403  strict_match);
404 }
405 
407  const AgentRoute *inet_rt,
408  bool strict_match) {
410  strict_match);
411 }
412 
414  const Agent *agent) {
415  MacAddress compute_mac;
416  VrfEntry *underlay_vrf = agent->fabric_policy_vrf();
417  InetUnicastRouteEntry *router_rt = NULL;
418  router_rt = underlay_vrf->GetUcRoute(compute_ip);
419  if (router_rt != NULL &&
420  router_rt->prefix_address() == compute_ip) {
421  const AgentPath *apath = FindPathWithGivenPeerAndNexthop(router_rt,
423  if (apath) {
424  const TunnelNH * tunl_nh =
425  dynamic_cast<const TunnelNH*>(apath->nexthop());
426  if (tunl_nh->GetDmac()) {
427  compute_mac = *(tunl_nh->GetDmac());
428  }
429  }
430  }
431  return compute_mac;
432 }
433 
434 //Finds route in a EVPN table
436  const std::string &vrf_name,
437  const IpAddress &ip_addr,
438  unsigned int prefix_len,
439  const autogen::EnetNextHopType &nh_item) {
440 
441  const unsigned int ethernet_tag = 0;
442 
443  EvpnRouteEntry *evpn_rt =
445  vrf_name,
446  MacAddress(),
447  ip_addr,
448  prefix_len,
449  ethernet_tag);
450  if (RoutePrefixIsEqualTo(evpn_rt, ip_addr, prefix_len)) {
451  return evpn_rt;
452  }
453  return NULL;
454 }
455 
456 //Finds route in an Inet table
458  const std::string &vrf_name,
459  const IpAddress &ip_addr,
460  unsigned int prefix_len,
461  const autogen::NextHopType &nh_item) {
462 
463  VrfEntry *vrf_entry =
464  agent->vrf_table()->FindVrfFromName(vrf_name);
465  if (vrf_entry == NULL)
466  return NULL;
467 
468  InetUnicastAgentRouteTable *inet_tbl =
469  vrf_entry->GetInetUnicastRouteTable(ip_addr);
470  if (inet_tbl == NULL)
471  return NULL;
472 
473  InetUnicastRouteEntry local_vm_route_key(inet_tbl->vrf_entry(),
474  ip_addr,
475  prefix_len, false);
476  InetUnicastRouteEntry *inet_rt =
477  dynamic_cast<InetUnicastRouteEntry *>
478  (inet_tbl->FindLPM(local_vm_route_key));
479  if (RoutePrefixIsEqualTo(inet_rt, ip_addr, prefix_len)) {
480  return inet_rt;
481  }
482  return NULL;
483 }
484 
485 static bool InitializeNhRequest(const NextHop *path_nh,
486  DBRequest &nh_req,
487  const std::string& vrf_name) {
488  NextHopKey * orig_key = dynamic_cast<NextHopKey*>(
489  path_nh->GetDBRequestKey().get())->Clone();
490 
491  if(orig_key == NULL) {
492  LOG(ERROR, "Error in InitializeNhRequest"
493  << ", orig_key == NULL");
494  assert(orig_key != NULL);
495  }
496 
497  nh_req.key.reset(orig_key);
498  if (path_nh->GetType() == NextHop::INTERFACE) {
499  InterfaceNHKey *intf_orig_key =
500  dynamic_cast<InterfaceNHKey*>(orig_key);
501  if(intf_orig_key == NULL) {
502  LOG(ERROR, "Error in InitializeNhRequest"
503  << ", intf_orig_key == NULL");
504  assert(intf_orig_key != NULL);
505  }
506  // if NH is an interface, then update flags
507  intf_orig_key->set_flags(intf_orig_key->flags() |
509  nh_req.data.reset(new InterfaceNHData(vrf_name));
510  } else if (path_nh->GetType() == NextHop::COMPOSITE) {
511  nh_req.data.reset(new CompositeNHData);
512  } else { // other types of NH are not expected here
513  LOG(ERROR, "Error in InitializeNhRequest"
514  << ", Wrong NH type:" << path_nh->GetType());
515  assert(
516  path_nh->GetType() == NextHop::INTERFACE ||
517  path_nh->GetType() == NextHop::COMPOSITE);
518  return false;
519  }
520  return true;
521 }
522 
523 //
524 // EVPN routes advertising
525 //
526 
527 static void AdvertiseLocalRoute(const IpAddress &prefix_ip,
528  const uint32_t plen,
529  DBRequest &nh_req,
530  const Peer *peer,
531  const RouteParameters& params,
532  EvpnAgentRouteTable *evpn_table
533 ) {
534  EvpnRoutingData *rt_data = new EvpnRoutingData(nh_req,
535  params.sg_list_,
536  params.communities_,
537  params.path_preference_,
538  params.ecmp_load_balance_,
539  params.tag_list_,
540  evpn_table->vrf_entry(),
541  evpn_table->vrf_entry()->vxlan_id(),
542  params.vn_list_);
543  evpn_table->AddType5Route(peer,
544  evpn_table->vrf_entry()->GetName(),
545  prefix_ip,
546  0, // ethernet_tag = 0 for Type5
547  rt_data,
548  plen);
549 }
550 
551 static void AdvertiseInterfaceBgpRoute(const IpAddress &prefix_ip,
552  const uint32_t plen,
553  DBRequest &nh_req,
554  const Peer *peer,
555  const AgentPath* path,
556  EvpnAgentRouteTable *evpn_table
557 ) {
558  const NextHop *path_nh = path->nexthop();
559 
560  const InterfaceNH *intf_nh = dynamic_cast<const InterfaceNH *>
561  (path_nh);
562  const Interface *intf = intf_nh->GetInterface();
563  if (intf->type() != Interface::VM_INTERFACE) {
564  return;
565  }
566  const VmInterface *vm_intf = dynamic_cast<const VmInterface*>
567  (intf);
568  DBEntryBase::KeyPtr tintf_key_ptr = vm_intf->GetDBRequestKey();
569  const VmInterfaceKey* intf_key_ptr =
570  dynamic_cast<const VmInterfaceKey *>(tintf_key_ptr.get());
571 
572  LocalVmRoute *loc_rt_ptr = new LocalVmRoute(
573  *intf_key_ptr,
574  MplsTable::kInvalidLabel, // mpls_label
575  path->vxlan_id(),
576  path->force_policy(),
577  path->dest_vn_list(),
578  intf_nh->GetFlags(), // flags
579  path->sg_list(),
580  path->tag_list(),
581  path->communities(),
582  path->path_preference(),
583  path->subnet_service_ip(),
584  path->ecmp_load_balance(),
585  path->is_local(),
586  path->is_health_check_service(),
587  path->sequence(),
588  path->etree_leaf(),
589  false); // native_encap
590  loc_rt_ptr->set_tunnel_bmap(TunnelType::VxlanType());
591 
592  {
594 
595  req.key.reset(new EvpnRouteKey(peer,
596  evpn_table->vrf_entry()->GetName(),
597  MacAddress(),
598  prefix_ip,
599  plen,
600  0));
601  req.data.reset(loc_rt_ptr);
602  evpn_table->Enqueue(&req);
603  }
604 }
605 
606 static void AdvertiseCompositeInterfaceBgpRoute(const IpAddress &prefix_ip,
607  const uint32_t plen,
608  DBRequest &nh_req,
609  const Peer *peer,
610  const AgentPath* path,
611  EvpnAgentRouteTable *evpn_table
612 ) {
613  const BgpPeer *bgp_peer = dynamic_cast<const BgpPeer*>(peer);
614  std::stringstream prefix_str;
615  prefix_str << prefix_ip.to_string();
616  prefix_str << "/";
617  prefix_str << plen;
618  std::string vrf_name = evpn_table->vrf_name();
619 
621  bgp_peer,
622  path->dest_vn_list(),
623  path->ecmp_load_balance(),
624  path->tag_list(),
625  path->sg_list(),
626  path->path_preference(),
628  nh_req,
629  prefix_str.str(),
630  evpn_table->vrf_name());
631 
633  rt_data->cloned_local_path_list().begin();
634  while (iter != rt_data->cloned_local_path_list().end()) {
635  evpn_table->AddClonedLocalPathReq(bgp_peer, vrf_name,
636  MacAddress(), prefix_ip, 0, (*iter));
637  iter++;
638  }
639 
640  evpn_table->AddRemoteVmRouteReq(bgp_peer,
641  vrf_name, MacAddress(),
642  prefix_ip,
643  plen,
644  0, // ethernet tag is 0 for VxLAN
645  rt_data);
646 }
647 
648 //
649 // Inet routes advertising
650 //
651 static void AdvertiseLocalRoute(const IpAddress &prefix_ip,
652  const uint32_t plen,
653  DBRequest &nh_req,
654  const Peer *peer,
655  const RouteParameters& params,
656  InetUnicastAgentRouteTable *inet_table,
657  const std::string& origin_vn
658 ) {
659  inet_table->AddEvpnRoutingRoute(prefix_ip,
660  plen,
661  inet_table->vrf_entry(),
662  peer,
663  params.sg_list_,
664  params.communities_,
665  params.path_preference_,
666  params.ecmp_load_balance_,
667  params.tag_list_,
668  nh_req,
669  inet_table->vrf_entry()->vxlan_id(),
670  params.vn_list_,
671  origin_vn);
672 }
673 
675  const uint32_t plen,
676  const Peer *peer,
677  EvpnAgentRouteTable *evpn_table) {
678 
679  if (peer != routing_vrf_interface_peer_) {
680  return;
681  }
682 
683  EvpnRouteEntry *rt_entry = evpn_table->FindRoute(MacAddress(),
684  prefix_ip, plen, 0);
685  if (rt_entry && RoutePrefixIsEqualTo(rt_entry, prefix_ip, plen)) {
686  // Delete the old non-BGP path if it exists
687  AgentPath *old_path = rt_entry->FindPath(peer);
688  if (old_path) {
689  rt_entry->DeletePathFromPeer(rt_entry->get_table_partition(),
690  evpn_table, old_path);
691  }
692  }
693 }
694 
696  const IpAddress &prefix_ip,
697  const uint32_t plen,
698  const Peer *peer,
699  const RouteParameters &params,
700  EvpnAgentRouteTable *evpn_table) {
701  const NextHop *path_nh = path != NULL ? path->nexthop() : NULL;
702 
703  if (path_nh == NULL) {
704  return;
705  }
706 
708  if (InitializeNhRequest(path_nh,
709  nh_req, evpn_table->vrf_entry()->GetName()) == false) {
710  return;
711  }
712 
713  if (peer->GetType() == Peer::BGP_PEER) {
714  if (path_nh->GetType() == NextHop::INTERFACE) {
716  prefix_ip, plen, nh_req, peer, path, evpn_table);
717  } else if (path_nh->GetType() == NextHop::COMPOSITE) {
719  prefix_ip, plen, nh_req, peer, path, evpn_table);
720  }
721  } else {
722  AdvertiseLocalRoute(prefix_ip, plen, nh_req, peer, params,
723  evpn_table);
724  }
725 }
726 
728  const uint32_t plen,
729  const Peer *peer,
730  InetUnicastAgentRouteTable *inet_table) {
731  if (peer != routing_vrf_interface_peer_) {
732  return;
733  }
734 
735  InetUnicastRouteEntry old_rt_key(inet_table->vrf_entry(),
736  prefix_ip, plen, false);
737  InetUnicastRouteEntry *rt_entry = inet_table->FindRouteUsingKey(old_rt_key);
738  if (rt_entry && RoutePrefixIsEqualTo(rt_entry, prefix_ip, plen)) {
739  // Delete the old non-BGP path if it exists
740  AgentPath *old_path = rt_entry->FindPath(peer);
741  if (old_path) {
742  rt_entry->DeletePathFromPeer(rt_entry->get_table_partition(),
743  inet_table, old_path);
744  }
745  }
746 }
747 
749  const IpAddress &prefix_ip,
750  const uint32_t plen,
751  const Peer *peer,
752  const RouteParameters &params,
753  InetUnicastAgentRouteTable *inet_table) {
754  const NextHop *path_nh = path != NULL ? path->nexthop() : NULL;
755  if (path_nh == NULL || inet_table == NULL || peer == NULL) {
756  return;
757  }
758 
759 
761  if (InitializeNhRequest(path_nh,
762  nh_req, inet_table->vrf_entry()->GetName()) == false) {
763  return;
764  }
765 
766  std::string origin_vn = "";
767  if (peer->GetType() == Peer::VXLAN_BGP_PEER) {
768  } else {
769  origin_vn = GetOriginVn(inet_table->vrf_entry(), prefix_ip, plen);
770  }
771  AdvertiseLocalRoute(prefix_ip, plen, nh_req, peer, params,
772  inet_table, origin_vn);
773 }
774 
775 
777  if (const_vrf == NULL) {
778  std::cout<< "VxlanRoutingManager::PrintEvpnTable"
779  << ", NULL vrf ptr"
780  << std::endl;
781  return;
782  }
783  VrfEntry* routing_vrf = const_cast<VrfEntry*>(const_vrf);
784  EvpnAgentRouteTable *evpn_table = dynamic_cast<EvpnAgentRouteTable *>
785  (routing_vrf->GetEvpnRouteTable());
786  if (evpn_table == NULL) {
787  std::cout<< "VxlanRoutingManager::PrintEvpnTable"
788  << ", NULL EVPN tbl ptr"
789  << std::endl;
790  return;
791  }
792  EvpnRouteEntry *c_entry = dynamic_cast<EvpnRouteEntry *>
793  (evpn_table->GetTablePartition(0)->GetFirst());
794  if (c_entry) {
795  if (c_entry->IsType5())
796  std::cout << "Evpn Type 5 table:" << std::endl;
797  else
798  std::cout << "Evpn Type 2 table:" << std::endl;
799  }
800  while (c_entry) {
801  const Route::PathList & path_list = c_entry->GetPathList();
802  std::cout<< " IP:" << c_entry->prefix_address()
803  << ", path count = " << path_list.size()
804  << ", ethernet_tag = " << c_entry->ethernet_tag()
805  << std::endl;
806  for (Route::PathList::const_iterator it = path_list.begin();
807  it != path_list.end(); ++it) {
808  const AgentPath* path =
809  dynamic_cast<const AgentPath*>(it.operator->());
810  if (!path)
811  continue;
812  std::cout<< " NH: "
813  << (path->nexthop() ? path->nexthop()->ToString() :
814  "NULL")
815  << ", " << "Peer:"
816  << (path->peer() ? path->peer()->GetName() : "NULL")
817  << std::endl;
818  if (path->nexthop()->GetType() == NextHop::COMPOSITE) {
819  CompositeNH *comp_nh = dynamic_cast<CompositeNH *>
820  (path->nexthop());
821  std::cout<< " n components="
822  << comp_nh->ComponentNHCount()
823  << std::endl;
824  }
825  }
826  if (evpn_table && evpn_table->GetTablePartition(0))
827  c_entry = dynamic_cast<EvpnRouteEntry *>
828  (evpn_table->GetTablePartition(0)->GetNext(c_entry));
829  else
830  break;
831  }
832 }
833 
835  if (const_vrf == NULL) {
836  std::cout<< "VxlanRoutingManager::PrintInetTable"
837  << ", NULL vrf ptr"
838  << std::endl;
839  return;
840  }
841  VrfEntry* routing_vrf = const_cast<VrfEntry*>(const_vrf);
842  InetUnicastAgentRouteTable *inet_table =
843  routing_vrf->GetInet4UnicastRouteTable();
844  if (inet_table == NULL) {
845  std::cout<< "VxlanRoutingManager::PrintInetTable"
846  << ", NULL Inet tbl ptr"
847  << std::endl;
848  return;
849  }
850  InetUnicastRouteEntry *c_entry = dynamic_cast<InetUnicastRouteEntry *>
851  (inet_table->GetTablePartition(0)->GetFirst());
852  if (c_entry) {
853  std::cout << "Inet table:" << std::endl;
854  }
855  while (c_entry) {
856  const Route::PathList & path_list = c_entry->GetPathList();
857  std::cout<< " IP:" << c_entry->prefix_address()
858  << ", path count = " << path_list.size() << std::endl;
859  for (Route::PathList::const_iterator it = path_list.begin();
860  it != path_list.end(); ++it) {
861  const AgentPath* path =
862  dynamic_cast<const AgentPath*>(it.operator->());
863  if (!path)
864  continue;
865  std::cout<< " NH: "
866  << (path->nexthop() ? path->nexthop()->ToString() :
867  "NULL")
868  << ", " << "Peer:"
869  << (path->peer() ? path->peer()->GetName() : "NULL")
870  << ", nh ptr = " << path->nexthop()
871  << ", pt ptr = " << path
872  << std::endl;
873  // if (path->nexthop()->GetType() == NextHop::COMPOSITE) {
874  // CompositeNH *comp_nh = dynamic_cast<CompositeNH *>
875  // (path->nexthop());
876  // std::cout<< " n components="
877  // << comp_nh->ComponentNHCount()
878  // << std::endl;
879  // }
880  }
881  if (inet_table && inet_table->GetTablePartition(0))
882  c_entry = dynamic_cast<InetUnicastRouteEntry *>
883  (inet_table->GetTablePartition(0)->GetNext(c_entry));
884  else
885  break;
886  }
887 }
888 
890  Agent *agent = Agent::GetInstance();
891  if (agent == NULL) {
892  std::cout<<"VxlanRoutingManager::ListAttachedVns agent == NULL"<<std::endl;
893  return;
894  }
895  VxlanRoutingManager *vxlan_rt_mgr = agent->oper_db()->vxlan_routing_manager();
896  if (vxlan_rt_mgr == NULL) {
897  std::cout<<"VxlanRoutingManager::ListAttachedVns rt mgr = NULL"<<std::endl;
898  return;
899  }
902  for(VxlanRoutingVrfMapper::LrVrfInfoMap::iterator it = lr_vrf_info_map.begin();
903  it != lr_vrf_info_map.end(); it++) {
904  std::cout << "VxlanRoutingManager::ListAttachedVns, "
905  << "rt VRF = "
906  << (*it).second.routing_vrf_->GetName()
907  << std::endl;
908  std::cout << "VxlanRoutingManager::ListAttachedVns, "
909  << "size = "
910  << (*it).second.bridge_vn_list_.size()
911  << std::endl;
913  (*it).second.bridge_vn_list_;
914  for(VxlanRoutingVrfMapper::RoutedVrfInfo::BridgeVnList::iterator it_br = reg_br.begin();
915  it_br != reg_br.end(); it_br++) {
916  if ((*it_br))
917  std::cout<< "VxlanRoutingManager::ListAttachedVns, "
918  << "br VN = " << (*it_br)->GetName()
919  << std::endl;
920  }
921  }
922 }
923 
924 //
925 //END-OF-FILE
926 //
boost::asio::ip::address IpAddress
Definition: address.h:13
boost::asio::ip::address_v4 Ip4Address
Definition: address.h:14
bool is_health_check_service() const
Definition: agent_path.h:380
uint32_t sequence() const
Definition: agent_path.h:328
bool is_local() const
Definition: agent_path.h:372
const VnListType & dest_vn_list() const
Definition: agent_path.h:258
NextHop * nexthop() const
Definition: agent_path.cc:87
const EcmpLoadBalance & ecmp_load_balance() const
Definition: agent_path.h:365
const PathPreference & path_preference() const
Definition: agent_path.h:329
const SecurityGroupList & sg_list() const
Definition: agent_path.h:248
uint32_t vxlan_id() const
Definition: agent_path.h:265
const Peer * peer() const
Definition: agent_path.h:263
bool force_policy() const
Definition: agent_path.h:270
const TagList & tag_list() const
Definition: agent_path.h:249
const IpAddress subnet_service_ip() const
Definition: agent_path.h:274
bool etree_leaf() const
Definition: agent_path.h:388
const CommunityList & communities() const
Definition: agent_path.h:250
virtual const PrefixType & prefix_address() const
Returns the value of a stored prefix address (IPv4, IPv6 or MAC address)
Definition: agent_route.h:389
const std::string & vrf_name() const
Definition: agent_route.cc:455
VrfEntry * vrf_entry() const
Definition: agent_route.cc:459
Base class for all Route entries in agent.
Definition: agent_route.h:224
VrfEntry * vrf() const
Definition: agent_route.h:275
void DeletePathFromPeer(DBTablePartBase *part, AgentRouteTable *table, AgentPath *path)
Definition: agent_route.cc:655
virtual AgentPath * FindPath(const Peer *peer) const
Definition: agent_route.cc:865
Definition: agent.h:360
OperDB * oper_db() const
Definition: agent.cc:1016
VrfTable * vrf_table() const
Definition: agent.h:487
VrfEntry * fabric_policy_vrf() const
Definition: agent.h:919
const Peer * evpn_routing_peer() const
Definition: agent.h:1029
static Agent * GetInstance()
Definition: agent.h:438
size_t ComponentNHCount() const
Definition: nexthop.h:1815
const NextHop * GetNH(uint32_t idx) const
Definition: nexthop.h:1832
ClonedLocalPathList::iterator ClonedLocalPathListIter
ClonedLocalPathList & cloned_local_path_list()
std::unique_ptr< DBRequestKey > KeyPtr
Definition: db_entry.h:24
virtual KeyPtr GetDBRequestKey() const =0
DBTablePartBase * get_table_partition() const
Definition: db_entry.cc:115
bool Enqueue(DBRequest *req)
Definition: db_table.cc:220
virtual DBEntryBase * GetNext(const DBEntryBase *)=0
virtual DBEntryBase * GetFirst()=0
virtual DBTablePartBase * GetTablePartition(const DBRequestKey *key)
Definition: db_table.cc:462
void AddClonedLocalPathReq(const Peer *peer, const string &vrf_name, const MacAddress &mac, const IpAddress &ip_addr, uint32_t ethernet_tag, ClonedLocalPath *data)
EvpnRouteEntry * FindRoute(const MacAddress &mac, const IpAddress &ip_addr, uint32_t plen, uint32_t ethernet_tag)
static void AddRemoteVmRouteReq(const Peer *peer, const std::string &vrf_name, const MacAddress &mac, const IpAddress &ip_addr, uint32_t plen, uint32_t ethernet_tag, AgentRouteData *data)
void AddType5Route(const Peer *peer, const std::string &vrf_name, const IpAddress &ip_addr, uint32_t ethernet_tag, EvpnRoutingData *data, uint8_t plen=0)
uint32_t ethernet_tag() const
uint8_t prefix_length() const
!
void AddEvpnRoutingRoute(const IpAddress &ip_addr, uint8_t plen, const VrfEntry *vrf, const Peer *peer, const SecurityGroupList &sg_list, const CommunityList &communities, const PathPreference &path_preference, const EcmpLoadBalance &ecmp_load_balance, const TagList &tag_list, DBRequest &nh_req, uint32_t vxlan_id, const VnListType &vn_list, const std::string &origin_vn="")
InetUnicastRouteEntry * FindRouteUsingKey(InetUnicastRouteEntry &key)
InetUnicastRouteEntry * FindLPM(const IpAddress &ip)
uint8_t prefix_length() const
!
void set_flags(uint8_t flags)
Definition: nexthop.h:1215
const uint8_t & flags() const
Definition: nexthop.h:1216
const Interface * GetInterface() const
Definition: nexthop.h:1293
uint8_t GetFlags() const
Definition: nexthop.h:1300
@ VM_INTERFACE
Definition: interface.h:37
Type type() const
Definition: interface.h:114
void set_tunnel_bmap(TunnelType::TypeBmap bmap)
Definition: agent_path.h:679
static const uint32_t kInvalidLabel
Definition: mpls.h:101
@ COMPOSITE
Definition: nexthop.h:354
@ INTERFACE
Definition: nexthop.h:351
@ TUNNEL
Definition: nexthop.h:352
@ VRF
Definition: nexthop.h:350
virtual std::string ToString() const
Definition: nexthop.h:368
Type GetType() const
Definition: nexthop.h:405
VxlanRoutingManager * vxlan_routing_manager() const
Definition: operdb_init.h:98
Definition: peer.h:44
const Type GetType() const
Definition: peer.h:87
Type
Definition: peer.h:48
@ BGP_PEER
Definition: peer.h:51
@ LOCAL_VM_PORT_PEER
Definition: peer.h:56
@ VXLAN_BGP_PEER
Definition: peer.h:55
const std::string & GetName() const
Definition: peer.h:86
const PathList & GetPathList() const
Definition: route.h:46
boost::intrusive::list< Path, PathListMember > PathList
Definition: route.h:20
const MacAddress * GetDmac() const
Definition: tunnel_nh.h:39
static TypeBmap VxlanType()
Definition: nexthop.h:311
KeyPtr GetDBRequestKey() const
Definition: vn.h:151
const std::vector< VnIpam > & GetVnIpam() const
Definition: vn.h:171
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
InetUnicastRouteEntry * GetUcRoute(const IpAddress &addr) const
Definition: vrf.cc:237
InetUnicastAgentRouteTable * GetInet4UnicastRouteTable() const
Definition: vrf.cc:319
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
VrfEntry * FindVrfFromName(const string &name)
Definition: vrf.cc:873
This class manages an operative state of VxLAN logical routers (LR) defined via Config logical-router...
static void ListAttachedVns()
Prints all virtual networks attached to logical routers.
static void CopyInterfacePathToEvpnTable(const AgentPath *path, const IpAddress &prefix_ip, const uint32_t plen, const Peer *peer, const RouteParameters &params, EvpnAgentRouteTable *evpn_table)
Copies the path to the prefix address into the EVPN table with the given Peer. The function is used d...
static bool RoutePrefixIsEqualTo(const EvpnRouteEntry *route, const IpAddress &prefix_ip, const uint32_t prefix_len)
Determines whether route prefix in the EVPN route is equal to the given pair of prefix IP address and...
bool HasBgpPeerPath(EvpnRouteEntry *evpn_rt)
Determines whether the given EVPN route has at least one path originating from BGP/XMPP (has Peer typ...
static bool IsVxlanAvailable(const Agent *agent)
Checks whether VxLAN routing manager is enabled or not.
const VxlanRoutingVrfMapper & vrf_mapper() const
Returns the map between LR uuids and associated bridge and routing VRF instances.
static bool is_ipv4_string(const std::string &prefix_str)
Determines whether the address string contains an IPv4 address as substring or not.
static uint32_t loc_sequence_
An always increasing counter for new paths (used to signal controoler about new routes).
static bool IsHostRoute(const IpAddress &prefix_ip, uint32_t prefix_len)
Determines whether the prefix address and the prefix length point to a host route (/32 for IPv4,...
static AgentRoute * FindEvpnOrInetRoute(const Agent *agent, const std::string &vrf_name, const IpAddress &ip_addr, uint32_t prefix_len, const autogen::EnetNextHopType &nh_item)
Finds a route with the given prefix address and len in the EVPN table.
static const AgentPath * FindPathWithGivenPeer(const AgentRoute *inet_rt, const Peer::Type peer_type)
Finds in the given route the path with a specified Peer type.
static std::string ipv6_prefix(const std::string &prefix_str)
Extracts an IPv6 address string from the prefix string.
std::string GetOriginVn(const VrfEntry *routing_vrf, const IpAddress &ip_addr, const uint8_t &plen)
Finds first occurence of a route with the given prefix (IP address and length) in Inet tables of brid...
static const AgentPath * FindInterfacePathWithLocalVmPeer(const AgentRoute *inet_rt, bool strict_match=true)
Finds in the given route the path which has the LOCAL_VM_PEER peer type and the Interface nexthop typ...
static uint32_t GetNewLocalSequence(const AgentPath *)
Auxilliary functions.
static const Peer * routing_vrf_interface_peer_
Internal data of this class.
static bool IsBridgeVrf(const VrfEntry *vrf)
Determines whether the pointer to the VRF instance is of bridge type.
static bool HasVrfNexthop(const AgentRoute *rt)
Determines whether the given route has the path with a VRF nexthop (VrfNH)
static const AgentPath * FindPathWithGivenPeerAndNexthop(const AgentRoute *inet_rt, const Peer::Type peer_type, const NextHop::Type nh_type, bool strict_match=true)
Finds in the given route the path with a specified Peer type and a specified nexthop type.
static void PrintEvpnTable(const VrfEntry *const_vrf)
Prints EVPN table of the given VRF instance.
bool IsHostRouteFromLocalSubnet(const EvpnRouteEntry *rt)
Determines whether the given EVPN route is a host one and belongs to a subnet of a local bridge VRF....
static bool IsRoutingVrf(const VrfEntry *vrf)
Determines whether the pointer to the VRF instance is of routing type.
static uint32_t ipv4_prefix_len(const std::string &prefix_str)
Extracts length of IPv4 subnet address from the prefix string.
static MacAddress NbComputeMac(const Ip4Address &compute_ip, const Agent *agent)
Returns the MAC address for the IP of a given neighbouring compute.
Agent * agent_
A pointer to the Agent instance.
void CopyPathToInetTable(const AgentPath *path, const IpAddress &prefix_ip, const uint32_t plen, const Peer *peer, const RouteParameters &params, InetUnicastAgentRouteTable *inet_table)
Copies the path to the prefix address into the EVPN table with the given Peer. The function is used d...
static const AgentPath * FindInterfacePathWithGivenPeer(const AgentRoute *inet_rt, const Peer::Type peer_type, bool strict_match=true)
Finds in the given route the path with the given Peer type and interface nexthop (InterfaceNH).
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...
bool IsVrfLocalRoute(EvpnRouteEntry *routing_evpn_rt, VrfEntry *bridge_vrf)
Determines if the given EVPN route has an interface NH or a composite of interfaces NH that belongs t...
static const AgentPath * FindInterfacePathWithBgpPeer(const AgentRoute *inet_rt, bool strict_match=true)
Finds in the given route the path which has the BGP_PEER Peer type and the Interface nexthop type....
static bool is_ipv6_string(const std::string &prefix_str)
Determines whether the address string contains an IPv6 address as substring or not.
static std::string ipv4_prefix(const std::string &prefix_str)
Extracts an IPv4 address string from the prefix string.
static void PrintInetTable(const VrfEntry *const_vrf)
Prints IPv4 Inet table of the given VRF instance.
static uint32_t ipv6_prefix_len(const std::string &prefix_str)
Extracts length of IPv6 subnet address from the prefix string.
VxlanRoutingVrfMapper vrf_mapper_
A map between LR uuids and associated bridge and routing VRF instances.
static void DeleteOldInterfacePath(const IpAddress &prefix_ip, const uint32_t plen, const Peer *peer, EvpnAgentRouteTable *evpn_table)
Routes copying functions.
This class is a storage for operative state of VxLAN logical routers (LRs) defined via Config logical...
LrVrfInfoMap lr_vrf_info_map_
The map between Logical router UUID and RoutedVrfInfo.
const boost::uuids::uuid GetLogicalRouterUuidUsingRoute(const AgentRoute *rt)
Find the UUID of the LR using a given route (AgentRoute).
std::map< boost::uuids::uuid, RoutedVrfInfo > LrVrfInfoMap
A typedef to store map between Logical router UUID and RoutedVrfInfo.
#define LOG(_Level, _Msg)
Definition: logging.h:34
@ 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
A structure to hold path parameters during the transfer (routes leaking) of data between VRF instance...
const EcmpLoadBalance & ecmp_load_balance_
A reference to EcmpLoadBalance of the path.
const TagList & tag_list_
A list of tags.
const PathPreference & path_preference_
A reference to the PathPreference of the path.
const CommunityList & communities_
A list of communities.
const SecurityGroupList & sg_list_
A list of security groups.
const VnListType & vn_list_
A list of path destination virtual networks used in policy lookups.
The structure holds information about virtual networks connected to a logical router (LR)
std::set< const VnEntry * > BridgeVnList
A typedef to store the list of bridge virtual networks connected to a 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.
boost::uuids::uuid uuid
static void AdvertiseInterfaceBgpRoute(const IpAddress &prefix_ip, const uint32_t plen, DBRequest &nh_req, const Peer *peer, const AgentPath *path, EvpnAgentRouteTable *evpn_table)
static bool IsGivenTypeCompositeNextHop(const NextHop *nh, NextHop::Type nh_type, bool strict_match=true)
static bool InitializeNhRequest(const NextHop *path_nh, DBRequest &nh_req, const std::string &vrf_name)
static void AdvertiseCompositeInterfaceBgpRoute(const IpAddress &prefix_ip, const uint32_t plen, DBRequest &nh_req, const Peer *peer, const AgentPath *path, EvpnAgentRouteTable *evpn_table)
static void AdvertiseLocalRoute(const IpAddress &prefix_ip, const uint32_t plen, DBRequest &nh_req, const Peer *peer, const RouteParameters &params, EvpnAgentRouteTable *evpn_table)