LCOV - code coverage report
Current view: top level - vnsw/agent/oper - vxlan_auxilliary.cc (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 23 486 4.7 %
Date: 2026-06-11 01:56:02 Functions: 4 41 9.8 %
Legend: Lines: hit not hit

          Line data    Source code
       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>
       8             : #include <controller/controller_init.h>
       9             : #include <controller/controller_route_path.h>
      10             : #include <xmpp_enet_types.h>
      11             : #include <xmpp_unicast_types.h>
      12             : #include <oper/tunnel_nh.h>
      13             : #include <oper/vxlan_routing_manager.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           0 : static bool IsGivenTypeCompositeNextHop(const NextHop *nh,
      25             :     NextHop::Type nh_type, bool strict_match = true) {
      26           0 :     if (nh->GetType() != NextHop::COMPOSITE) {
      27           0 :         return false;
      28             :     }
      29             :     const CompositeNH *composite_nh =
      30           0 :         dynamic_cast<const CompositeNH*>(nh);
      31           0 :     uint32_t comp_nh_count = composite_nh->ComponentNHCount();
      32           0 :     for (uint32_t i=0; i < comp_nh_count; i++) {
      33           0 :         const NextHop * c_nh = composite_nh->GetNH(i);
      34           0 :         if (c_nh != NULL) {
      35             :             // return true if at least one componet is interface
      36           0 :             if (c_nh->GetType() == nh_type &&
      37           0 :                 !strict_match) {
      38           0 :                 return true;
      39             :             }
      40             :             // return true only if all components are interfaces
      41           0 :             if (c_nh->GetType() != nh_type &&
      42             :                 strict_match) {
      43           0 :                 return false;
      44             :             }
      45             :         }
      46             :     }
      47           0 :     return strict_match;
      48             : }
      49             : 
      50             : //
      51             : // VxlanRoutingManager members
      52             : //
      53             : 
      54           0 : uint32_t VxlanRoutingManager::GetNewLocalSequence(const AgentPath* path) {
      55           0 :     const NextHop *path_nh = path->nexthop();
      56           0 :     if (path_nh->GetType() != NextHop::COMPOSITE) {
      57           0 :         return 0;
      58             :     }
      59           0 :     loc_sequence_++;
      60           0 :     return loc_sequence_;
      61             : }
      62             : 
      63           0 : bool VxlanRoutingManager::is_ipv4_string(const std::string& prefix_str) {
      64           0 :     return (prefix_str.find(".") != std::string::npos);
      65             : }
      66             : 
      67           0 : bool VxlanRoutingManager::is_ipv6_string(const std::string& prefix_str) {
      68           0 :     return (prefix_str.find(":") != std::string::npos) &&
      69           0 :             !is_ipv4_string(prefix_str);
      70             : }
      71             : 
      72           0 : uint32_t VxlanRoutingManager::ipv4_prefix_len(const std::string& prefix_str) {
      73           0 :     const std::string::size_type slash_pos = prefix_str.rfind("/");
      74           0 :     if (slash_pos == std::string::npos) {
      75           0 :         return 32;
      76             :     }
      77           0 :     const std::string len_str = prefix_str.substr(slash_pos + 1);
      78           0 :     uint32_t prefix_len = 0;
      79           0 :     std::istringstream(len_str) >> prefix_len;
      80           0 :     return std::min(uint32_t(32), prefix_len);
      81           0 : }
      82             : 
      83           0 : std::string VxlanRoutingManager::ipv4_prefix(const std::string& prefix_str) {
      84           0 :     std::string::size_type first_dot_pos = 0;
      85             :     std::string::size_type last_colon_pos =
      86           0 :         prefix_str.rfind(":");
      87           0 :     std::string::size_type slash_pos = prefix_str.rfind("/");
      88           0 :     std::string ip_str = "0.0.0.0";
      89           0 :     if ((first_dot_pos = prefix_str.find(".")) != std::string::npos) {
      90           0 :         if (first_dot_pos - last_colon_pos >= 2 &&
      91           0 :             first_dot_pos - last_colon_pos <= 4) {
      92           0 :                 ip_str = prefix_str.substr(last_colon_pos + 1);
      93             :         }
      94           0 :         if (last_colon_pos == string::npos) {
      95           0 :             ip_str = prefix_str;
      96             :         }
      97           0 :         if (slash_pos != string::npos) {
      98           0 :             ip_str = ip_str.substr(0, slash_pos);
      99             :         }
     100             :     }
     101           0 :     return ip_str;
     102           0 : }
     103             : 
     104           0 : uint32_t VxlanRoutingManager::ipv6_prefix_len(const std::string& prefix_str) {
     105           0 :     const std::string::size_type slash_pos = prefix_str.rfind("/");
     106           0 :     if (slash_pos == std::string::npos) {
     107           0 :         return 128;
     108             :     }
     109           0 :     const std::string len_str = prefix_str.substr(slash_pos + 1);
     110           0 :     uint32_t prefix_len = 0;
     111           0 :     std::istringstream(len_str) >> prefix_len;
     112           0 :     return std::min(uint32_t(128), prefix_len);
     113           0 : }
     114             : 
     115           0 : std::string VxlanRoutingManager::ipv6_prefix(const std::string& prefix_str) {
     116           0 :     const std::string zero_mac_str = "00:00:00:00:00:00";
     117           0 :     const std::string::size_type mac_pos = prefix_str.find(zero_mac_str);
     118           0 :     std::string ip_str = prefix_str;
     119             : 
     120           0 :     if (mac_pos != std::string::npos) {
     121           0 :         ip_str = prefix_str.substr(mac_pos + zero_mac_str.size() + 1);
     122             :     }
     123             : 
     124           0 :     const std::string::size_type slash_pos = ip_str.rfind("/");
     125           0 :     if (slash_pos != std::string::npos) {
     126           0 :         ip_str = ip_str.substr(0, slash_pos);
     127             :     }
     128           0 :     if (ip_str.find(":") == std::string::npos) {
     129           0 :         ip_str = "::";
     130             :     }
     131           0 :     return ip_str;
     132           0 : }
     133             : 
     134          35 : bool VxlanRoutingManager::IsVxlanAvailable(const Agent* agent) {
     135          35 :     VxlanRoutingManager *vxlan_rt_mgr = NULL;
     136          35 :     if (agent->oper_db()) {
     137          35 :         vxlan_rt_mgr = agent->oper_db()->vxlan_routing_manager();
     138             :     }
     139          35 :     if (vxlan_rt_mgr == NULL) {
     140           0 :         return false;
     141             :     }
     142          35 :     return true;
     143             : }
     144             : 
     145           0 : std::string VxlanRoutingManager::GetOriginVn(const VrfEntry *routing_vrf,
     146             :     const IpAddress& ip_addr,
     147             :     const uint8_t& plen) {
     148             : 
     149           0 :     std::string origin_vn = "";
     150           0 :     if (routing_vrf->vn()) {
     151             :         VxlanRoutingVrfMapper::RoutedVrfInfo &lr_vrf_info =
     152             :             vrf_mapper_.lr_vrf_info_map_
     153           0 :             [routing_vrf->vn()->logical_router_uuid()];
     154           0 :         for (auto bridge_vn_entry : lr_vrf_info.bridge_vn_list_) {
     155           0 :             VrfEntry* it_vrf = VnVrf(bridge_vn_entry, lr_vrf_info.bridge_vrf_names_list_[bridge_vn_entry]);
     156           0 :             if (it_vrf == nullptr) {
     157           0 :                 continue;
     158             :             }
     159           0 :             InetUnicastRouteEntry *rt = it_vrf->GetUcRoute(ip_addr);
     160           0 :             if (rt && RoutePrefixIsEqualTo(rt, ip_addr, plen)) {
     161           0 :                 origin_vn = bridge_vn_entry->GetName();
     162           0 :                 break;
     163             :             }
     164             :         }
     165             :     }
     166             : 
     167           0 :     return origin_vn;
     168           0 : }
     169             : 
     170           0 : bool VxlanRoutingManager::RoutePrefixIsEqualTo(const EvpnRouteEntry* route,
     171             :     const IpAddress& prefix_ip,
     172             :     const uint32_t prefix_len) {
     173           0 :     if (route == NULL ||
     174           0 :         route->prefix_address() != prefix_ip ||
     175           0 :         route->prefix_length() != prefix_len) {
     176           0 :         return false;
     177             :     }
     178           0 :     return true;
     179             : }
     180             : 
     181           0 : bool VxlanRoutingManager::RoutePrefixIsEqualTo(const InetUnicastRouteEntry* route,
     182             :         const IpAddress& prefix_ip,
     183             :         const uint32_t prefix_len) {
     184           0 :     if (route == NULL ||
     185           0 :         route->prefix_address() != prefix_ip ||
     186           0 :         route->prefix_length() != prefix_len) {
     187           0 :         return false;
     188             :     }
     189           0 :     return true;
     190             : }
     191             : 
     192           0 : bool VxlanRoutingManager::IsHostRoute(const IpAddress& prefix_ip, uint32_t prefix_len) {
     193           0 :     if (prefix_ip.is_v4() && prefix_len == 32)
     194           0 :         return true;
     195           0 :     if (prefix_ip.is_v6() && prefix_len == 128)
     196           0 :         return true;
     197           0 :     return false;
     198             : }
     199             : 
     200           0 : bool VxlanRoutingManager::IsHostRoute(const EvpnRouteEntry *evpn_rt) {
     201           0 :     if (evpn_rt != NULL) {
     202           0 :         return IsHostRoute(evpn_rt->prefix_address(), evpn_rt->prefix_length());
     203             :     }
     204           0 :     return false;
     205             : }
     206             : 
     207           0 : bool VxlanRoutingManager::IsHostRouteFromLocalSubnet(const EvpnRouteEntry *rt) {
     208           0 :     if(rt->vrf() == NULL || rt->vrf()->vn() == NULL){
     209           0 :         LOG(ERROR, "Error in VxlanRoutingManager::IsHostRouteFromLocalSubnet"
     210             :         << ", vrf == NULL || vrf()->vn() == NULL");
     211           0 :         assert(rt->vrf() && rt->vrf()->vn());
     212             :     }
     213             : 
     214           0 :     if (IsHostRoute(rt) == false) {
     215           0 :         return false;
     216             :     }
     217             : 
     218             :     const boost::uuids::uuid lr_uuid =
     219           0 :         vrf_mapper_.GetLogicalRouterUuidUsingRoute(rt);
     220           0 :     if (lr_uuid == boost::uuids::nil_uuid()) {
     221           0 :         return false;
     222             :     }
     223             : 
     224             :     const VxlanRoutingVrfMapper::RoutedVrfInfo& vr_info =
     225           0 :         vrf_mapper_.lr_vrf_info_map_[lr_uuid];
     226           0 :     const VxlanRoutingVrfMapper::RoutedVrfInfo::BridgeVnList& bridge_vns =
     227             :         vr_info.bridge_vn_list_;
     228             : 
     229           0 :     const VnEntry *bridge_vn = NULL;
     230             :     VxlanRoutingVrfMapper::RoutedVrfInfo::BridgeVnListIter it_br =
     231           0 :         bridge_vns.begin();
     232           0 :     while (it_br != bridge_vns.end()) {
     233           0 :         bridge_vn = *it_br;
     234           0 :         const std::vector<VnIpam> &VnIpams = bridge_vn->GetVnIpam();
     235           0 :         for (uint32_t j=0; j < VnIpams.size(); j++) {
     236           0 :             if (VnIpams[j].IsSubnetMember(rt->prefix_address())) {
     237           0 :                 return true;
     238             :             }
     239             :         }
     240           0 :         it_br++;
     241             :     }
     242           0 :     return false;
     243             : }
     244             : 
     245           0 : bool VxlanRoutingManager::IsVrfLocalRoute(EvpnRouteEntry *routing_evpn_rt,
     246             :     VrfEntry *bridge_vrf) {
     247             :     // check that the Inet table holds the corresponding route
     248             :     InetUnicastRouteEntry local_vm_route_key(
     249             :         bridge_vrf,
     250           0 :         routing_evpn_rt->prefix_address(),
     251           0 :         routing_evpn_rt->prefix_length(), false);
     252             : 
     253             :     InetUnicastAgentRouteTable *inet_table =
     254           0 :         bridge_vrf->GetInetUnicastRouteTable(routing_evpn_rt->prefix_address());
     255             :     InetUnicastRouteEntry *inet_rt =
     256             :         dynamic_cast<InetUnicastRouteEntry *>
     257           0 :         (inet_table->FindLPM(local_vm_route_key));
     258           0 :     if (inet_rt && RoutePrefixIsEqualTo(inet_rt, routing_evpn_rt->prefix_address(),
     259           0 :         routing_evpn_rt->prefix_length())) {
     260           0 :         return inet_rt->FindPath(agent_->evpn_routing_peer()) ? false : true;
     261             :     }
     262           0 :     return false;
     263           0 : }
     264             : 
     265           0 : bool VxlanRoutingManager::HasVrfNexthop(const AgentRoute* rt) {
     266           0 :     const Route::PathList & path_list = rt->GetPathList();
     267           0 :     for (Route::PathList::const_iterator it = path_list.begin();
     268           0 :         it != path_list.end(); ++it) {
     269             :         const AgentPath* path =
     270           0 :             dynamic_cast<const AgentPath*>(it.operator->());
     271             : 
     272           0 :         if (path != NULL &&
     273           0 :             path->nexthop() != NULL &&
     274           0 :             path->nexthop()->GetType() == NextHop::VRF) {
     275           0 :             return true;
     276             :         }
     277             :     }
     278           0 :     return false;
     279             : }
     280             : 
     281           0 : bool VxlanRoutingManager::HasBgpPeerPath(EvpnRouteEntry *evpn_rt) {
     282           0 :     const Route::PathList & path_list = evpn_rt->GetPathList();
     283           0 :     for (Route::PathList::const_iterator it = path_list.begin();
     284           0 :         it != path_list.end(); ++it) {
     285             :         const AgentPath* path =
     286           0 :             dynamic_cast<const AgentPath*>(it.operator->());
     287           0 :         if (path != NULL &&
     288           0 :             path->peer() != NULL &&
     289           0 :             path->peer()->GetType() == Peer::BGP_PEER) {
     290           0 :             return true;
     291             :         }
     292             :     }
     293           0 :     return false;
     294             : }
     295             : 
     296         191 : bool VxlanRoutingManager::IsRoutingVrf(const VrfEntry* vrf) {
     297         293 :     return vrf && vrf->vn() &&
     298         293 :         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             : 
     317         133 : bool VxlanRoutingManager::IsBridgeVrf(const VrfEntry* vrf) {
     318         202 :     return vrf && vrf->vn() &&
     319         202 :         !vrf->vn()->vxlan_routing_vn();
     320             : }
     321             : 
     322             : 
     323          35 : bool VxlanRoutingManager::IsRoutingVrf(const std::string vrf_name,
     324             :     const Agent* agent) {
     325          35 :     VxlanRoutingManager *vxlan_rt_mgr = NULL;
     326          35 :     const VrfEntry *vrf_cand = NULL;
     327          35 :     if (agent->oper_db()) {
     328          35 :         vxlan_rt_mgr = agent->oper_db()->vxlan_routing_manager();
     329             :     }
     330          35 :     if (vxlan_rt_mgr == NULL) {
     331           0 :         return false;
     332             :     }
     333          35 :     if (agent->vrf_table())
     334          35 :         vrf_cand = agent->vrf_table()->FindVrfFromName(vrf_name);
     335          35 :     if (vrf_cand == NULL) {
     336           1 :         return false;
     337             :     }
     338          34 :     return vxlan_rt_mgr->IsRoutingVrf(vrf_cand);
     339             : }
     340             : 
     341           0 : const AgentPath* VxlanRoutingManager::FindPathWithGivenPeer(
     342             :     const AgentRoute *inet_rt,
     343             :     const Peer::Type peer_type) {
     344           0 :     if (inet_rt == NULL)
     345           0 :         return NULL;
     346             : 
     347           0 :     const Route::PathList & path_list = inet_rt->GetPathList();
     348           0 :     for (Route::PathList::const_iterator it = path_list.begin();
     349           0 :         it != path_list.end(); ++it) {
     350             :         const AgentPath* path =
     351           0 :             dynamic_cast<const AgentPath*>(it.operator->());
     352             : 
     353           0 :         if (path != NULL &&
     354           0 :             path->peer()->GetType() == peer_type) {
     355           0 :                 return path;
     356             :         }
     357             :     }
     358           0 :     return NULL;
     359             : }
     360             : 
     361           0 : const AgentPath* VxlanRoutingManager::FindPathWithGivenPeerAndNexthop(
     362             :     const AgentRoute *route,
     363             :     const Peer::Type peer_type,
     364             :     const NextHop::Type nh_type,
     365             :     bool strict_match) {
     366           0 :     if (route == NULL)
     367           0 :         return NULL;
     368             : 
     369           0 :     const Route::PathList & path_list = route->GetPathList();
     370           0 :     for (Route::PathList::const_iterator it = path_list.begin();
     371           0 :         it != path_list.end(); ++it) {
     372             :         const AgentPath* path =
     373           0 :             dynamic_cast<const AgentPath*>(it.operator->());
     374             : 
     375           0 :         if (path != NULL &&
     376           0 :             path->nexthop() != NULL &&
     377           0 :             path->peer() != NULL &&
     378           0 :             path->peer()->GetType() == peer_type) {
     379           0 :             if (path->nexthop()->GetType() == nh_type) {
     380           0 :                 return path;
     381             :             }
     382           0 :             if (IsGivenTypeCompositeNextHop(path->nexthop(), nh_type,
     383             :                 strict_match)) {
     384           0 :                 return path;
     385             :             }
     386             :         }
     387             :     }
     388           0 :     return NULL;
     389             : }
     390             : 
     391           0 : const AgentPath* VxlanRoutingManager::FindInterfacePathWithGivenPeer(
     392             :     const AgentRoute *inet_rt,
     393             :     const Peer::Type peer_type,
     394             :     bool strict_match) {
     395           0 :     return FindPathWithGivenPeerAndNexthop(inet_rt,
     396           0 :         peer_type, NextHop::INTERFACE, strict_match);
     397             : }
     398             : 
     399           0 : const AgentPath *VxlanRoutingManager::FindInterfacePathWithBgpPeer(
     400             :     const AgentRoute *inet_rt,
     401             :     bool strict_match) {
     402           0 :     return FindInterfacePathWithGivenPeer(inet_rt, Peer::BGP_PEER,
     403           0 :         strict_match);
     404             : }
     405             : 
     406           0 : const AgentPath* VxlanRoutingManager::FindInterfacePathWithLocalVmPeer(
     407             :     const AgentRoute *inet_rt,
     408             :     bool strict_match) {
     409           0 :     return FindInterfacePathWithGivenPeer(inet_rt, Peer::LOCAL_VM_PORT_PEER,
     410           0 :         strict_match);
     411             : }
     412             : 
     413           0 : MacAddress VxlanRoutingManager::NbComputeMac(const Ip4Address& compute_ip,
     414             :     const Agent *agent) {
     415           0 :     MacAddress compute_mac;
     416           0 :     VrfEntry *underlay_vrf = agent->fabric_policy_vrf();
     417           0 :     InetUnicastRouteEntry *router_rt = NULL;
     418           0 :     router_rt = underlay_vrf->GetUcRoute(compute_ip);
     419           0 :     if (router_rt != NULL &&
     420           0 :         router_rt->prefix_address() == compute_ip) {
     421           0 :         const AgentPath *apath = FindPathWithGivenPeerAndNexthop(router_rt,
     422             :             Peer::BGP_PEER, NextHop::TUNNEL);
     423           0 :         if (apath) {
     424             :             const TunnelNH * tunl_nh =
     425           0 :                 dynamic_cast<const TunnelNH*>(apath->nexthop());
     426           0 :             if (tunl_nh->GetDmac()) {
     427           0 :                 compute_mac = *(tunl_nh->GetDmac());
     428             :             }
     429             :         }
     430             :     }
     431           0 :     return compute_mac;
     432             : }
     433             : 
     434             : //Finds route in a EVPN table
     435           0 : AgentRoute *VxlanRoutingManager::FindEvpnOrInetRoute(const Agent *agent,
     436             :     const std::string &vrf_name,
     437             :     const IpAddress &ip_addr,
     438             :     unsigned int prefix_len,
     439             :     const autogen::EnetNextHopType &nh_item) {
     440             : 
     441           0 :     const unsigned int ethernet_tag = 0;
     442             : 
     443             :     EvpnRouteEntry *evpn_rt =
     444           0 :         EvpnAgentRouteTable::FindRoute(agent,
     445             :             vrf_name,
     446           0 :             MacAddress(),
     447             :             ip_addr,
     448             :             prefix_len,
     449             :             ethernet_tag);
     450           0 :     if (RoutePrefixIsEqualTo(evpn_rt, ip_addr, prefix_len)) {
     451           0 :         return evpn_rt;
     452             :     }
     453           0 :     return NULL;
     454             : }
     455             : 
     456             : //Finds route in an Inet table
     457           0 : AgentRoute *VxlanRoutingManager::FindEvpnOrInetRoute(const Agent *agent,
     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           0 :         agent->vrf_table()->FindVrfFromName(vrf_name);
     465           0 :     if (vrf_entry == NULL)
     466           0 :         return NULL;
     467             : 
     468             :     InetUnicastAgentRouteTable *inet_tbl =
     469           0 :         vrf_entry->GetInetUnicastRouteTable(ip_addr);
     470           0 :     if (inet_tbl == NULL)
     471           0 :         return NULL;
     472             : 
     473             :     InetUnicastRouteEntry local_vm_route_key(inet_tbl->vrf_entry(),
     474             :         ip_addr,
     475           0 :         prefix_len, false);
     476             :     InetUnicastRouteEntry *inet_rt =
     477             :         dynamic_cast<InetUnicastRouteEntry *>
     478           0 :         (inet_tbl->FindLPM(local_vm_route_key));
     479           0 :     if (RoutePrefixIsEqualTo(inet_rt, ip_addr, prefix_len)) {
     480           0 :         return inet_rt;
     481             :     }
     482           0 :     return NULL;
     483           0 : }
     484             : 
     485           0 : static bool InitializeNhRequest(const NextHop *path_nh,
     486             :     DBRequest &nh_req,
     487             :     const std::string& vrf_name) {
     488           0 :     NextHopKey * orig_key = dynamic_cast<NextHopKey*>(
     489           0 :         path_nh->GetDBRequestKey().get())->Clone();
     490             : 
     491           0 :     if(orig_key == NULL) {
     492           0 :         LOG(ERROR, "Error in InitializeNhRequest"
     493             :         << ", orig_key == NULL");
     494           0 :         assert(orig_key != NULL);
     495             :     }
     496             : 
     497           0 :     nh_req.key.reset(orig_key);
     498           0 :     if (path_nh->GetType() == NextHop::INTERFACE) {
     499             :         InterfaceNHKey *intf_orig_key =
     500           0 :             dynamic_cast<InterfaceNHKey*>(orig_key);
     501           0 :         if(intf_orig_key == NULL) {
     502           0 :             LOG(ERROR, "Error in InitializeNhRequest"
     503             :             << ", intf_orig_key == NULL");
     504           0 :             assert(intf_orig_key != NULL);
     505             :         }
     506             :         // if NH is an interface, then update flags
     507           0 :         intf_orig_key->set_flags(intf_orig_key->flags() |
     508             :             InterfaceNHFlags::VXLAN_ROUTING);
     509           0 :         nh_req.data.reset(new InterfaceNHData(vrf_name));
     510           0 :     } else if (path_nh->GetType() == NextHop::COMPOSITE) {
     511           0 :         nh_req.data.reset(new CompositeNHData);
     512             :     } else {  // other types of NH are not expected here
     513           0 :         LOG(ERROR, "Error in InitializeNhRequest"
     514             :         << ", Wrong NH type:" << path_nh->GetType());
     515           0 :         assert(
     516             :             path_nh->GetType() == NextHop::INTERFACE ||
     517             :             path_nh->GetType() == NextHop::COMPOSITE);
     518           0 :         return false;
     519             :     }
     520           0 :     return true;
     521             : }
     522             : 
     523             : //
     524             : // EVPN routes advertising
     525             : //
     526             : 
     527           0 : 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           0 :         evpn_table->vrf_entry(),
     541           0 :         evpn_table->vrf_entry()->vxlan_id(),
     542           0 :         params.vn_list_);
     543           0 :     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           0 : }
     550             : 
     551           0 : 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           0 :     const NextHop *path_nh = path->nexthop();
     559             : 
     560           0 :     const InterfaceNH *intf_nh = dynamic_cast<const InterfaceNH *>
     561           0 :         (path_nh);
     562           0 :     const Interface *intf = intf_nh->GetInterface();
     563           0 :     if (intf->type() != Interface::VM_INTERFACE) {
     564           0 :         return;
     565             :     }
     566           0 :     const VmInterface *vm_intf = dynamic_cast<const VmInterface*>
     567           0 :         (intf);
     568           0 :     DBEntryBase::KeyPtr tintf_key_ptr = vm_intf->GetDBRequestKey();
     569             :     const VmInterfaceKey* intf_key_ptr =
     570           0 :         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           0 :         path->vxlan_id(),
     576           0 :         path->force_policy(),
     577           0 :         path->dest_vn_list(),
     578           0 :         intf_nh->GetFlags(),  // flags
     579           0 :         path->sg_list(),
     580           0 :         path->tag_list(),
     581           0 :         path->communities(),
     582           0 :         path->path_preference(),
     583           0 :         path->subnet_service_ip(),
     584           0 :         path->ecmp_load_balance(),
     585           0 :         path->is_local(),
     586           0 :         path->is_health_check_service(),
     587           0 :         path->sequence(),
     588           0 :         path->etree_leaf(),
     589           0 :         false);  // native_encap
     590           0 :         loc_rt_ptr->set_tunnel_bmap(TunnelType::VxlanType());
     591             : 
     592             :     {
     593           0 :         DBRequest req(DBRequest::DB_ENTRY_ADD_CHANGE);
     594             : 
     595           0 :         req.key.reset(new EvpnRouteKey(peer,
     596           0 :             evpn_table->vrf_entry()->GetName(),
     597           0 :             MacAddress(),
     598             :             prefix_ip,
     599             :             plen,
     600           0 :             0));
     601           0 :         req.data.reset(loc_rt_ptr);
     602           0 :         evpn_table->Enqueue(&req);
     603           0 :     }
     604           0 : }
     605             : 
     606           0 : 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           0 :     const BgpPeer *bgp_peer = dynamic_cast<const BgpPeer*>(peer);
     614           0 :     std::stringstream prefix_str;
     615           0 :     prefix_str << prefix_ip.to_string();
     616           0 :     prefix_str << "/";
     617           0 :     prefix_str << plen;
     618           0 :     std::string vrf_name = evpn_table->vrf_name();
     619             : 
     620             :     ControllerEcmpRoute *rt_data = new ControllerEcmpRoute(
     621             :         bgp_peer,
     622           0 :         path->dest_vn_list(),
     623           0 :         path->ecmp_load_balance(),
     624           0 :         path->tag_list(),
     625           0 :         path->sg_list(),
     626           0 :         path->path_preference(),
     627           0 :         TunnelType::VxlanType(),
     628             :         nh_req,
     629           0 :         prefix_str.str(),
     630           0 :         evpn_table->vrf_name());
     631             : 
     632             :     ControllerEcmpRoute::ClonedLocalPathListIter iter =
     633           0 :         rt_data->cloned_local_path_list().begin();
     634           0 :     while (iter != rt_data->cloned_local_path_list().end()) {
     635           0 :         evpn_table->AddClonedLocalPathReq(bgp_peer, vrf_name,
     636           0 :             MacAddress(), prefix_ip, 0, (*iter));
     637           0 :         iter++;
     638             :     }
     639             : 
     640           0 :     evpn_table->AddRemoteVmRouteReq(bgp_peer,
     641           0 :         vrf_name, MacAddress(),
     642             :         prefix_ip,
     643             :         plen,
     644             :         0,  // ethernet tag is 0 for VxLAN
     645             :         rt_data);
     646           0 : }
     647             : 
     648             : //
     649             : // Inet routes advertising
     650             : //
     651           0 : 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           0 :     inet_table->AddEvpnRoutingRoute(prefix_ip,
     660             :         plen,
     661           0 :         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           0 : }
     673             : 
     674           0 : void VxlanRoutingManager::DeleteOldInterfacePath(const IpAddress &prefix_ip,
     675             :     const uint32_t plen,
     676             :     const Peer *peer,
     677             :     EvpnAgentRouteTable *evpn_table) {
     678             : 
     679           0 :     if (peer != routing_vrf_interface_peer_) {
     680           0 :         return;
     681             :     }
     682             : 
     683           0 :     EvpnRouteEntry *rt_entry = evpn_table->FindRoute(MacAddress(),
     684             :         prefix_ip, plen, 0);
     685           0 :     if (rt_entry && RoutePrefixIsEqualTo(rt_entry, prefix_ip, plen)) {
     686             :         // Delete the old non-BGP path if it exists
     687           0 :         AgentPath *old_path = rt_entry->FindPath(peer);
     688           0 :         if (old_path) {
     689           0 :             rt_entry->DeletePathFromPeer(rt_entry->get_table_partition(),
     690             :                 evpn_table, old_path);
     691             :         }
     692             :     }
     693             : }
     694             : 
     695           0 : void VxlanRoutingManager::CopyInterfacePathToEvpnTable(const AgentPath* path,
     696             :     const IpAddress &prefix_ip,
     697             :     const uint32_t plen,
     698             :     const Peer *peer,
     699             :     const RouteParameters &params,
     700             :     EvpnAgentRouteTable *evpn_table) {
     701           0 :     const NextHop *path_nh = path != NULL ? path->nexthop() : NULL;
     702             : 
     703           0 :     if (path_nh == NULL) {
     704           0 :         return;
     705             :     }
     706             : 
     707           0 :     DBRequest nh_req(DBRequest::DB_ENTRY_ADD_CHANGE);
     708           0 :     if (InitializeNhRequest(path_nh,
     709           0 :         nh_req, evpn_table->vrf_entry()->GetName()) == false) {
     710           0 :         return;
     711             :     }
     712             : 
     713           0 :     if (peer->GetType() == Peer::BGP_PEER) {
     714           0 :         if (path_nh->GetType() == NextHop::INTERFACE) {
     715           0 :             AdvertiseInterfaceBgpRoute(
     716             :                 prefix_ip, plen, nh_req, peer, path, evpn_table);
     717           0 :         } else if (path_nh->GetType() == NextHop::COMPOSITE) {
     718           0 :             AdvertiseCompositeInterfaceBgpRoute(
     719             :                 prefix_ip, plen, nh_req, peer, path, evpn_table);
     720             :         }
     721             :     } else {
     722           0 :         AdvertiseLocalRoute(prefix_ip, plen, nh_req, peer, params,
     723             :             evpn_table);
     724             :     }
     725           0 : }
     726             : 
     727           0 : void VxlanRoutingManager::DeleteOldInterfacePath(const IpAddress &prefix_ip,
     728             :     const uint32_t plen,
     729             :     const Peer *peer,
     730             :     InetUnicastAgentRouteTable *inet_table) {
     731           0 :     if (peer != routing_vrf_interface_peer_) {
     732           0 :         return;
     733             :     }
     734             : 
     735             :     InetUnicastRouteEntry old_rt_key(inet_table->vrf_entry(),
     736           0 :        prefix_ip, plen, false);
     737           0 :     InetUnicastRouteEntry *rt_entry = inet_table->FindRouteUsingKey(old_rt_key);
     738           0 :     if (rt_entry && RoutePrefixIsEqualTo(rt_entry, prefix_ip, plen)) {
     739             :         // Delete the old non-BGP path if it exists
     740           0 :         AgentPath *old_path = rt_entry->FindPath(peer);
     741           0 :         if (old_path) {
     742           0 :             rt_entry->DeletePathFromPeer(rt_entry->get_table_partition(),
     743             :                 inet_table, old_path);
     744             :         }
     745             :     }
     746           0 : }
     747             : 
     748           0 : void VxlanRoutingManager::CopyPathToInetTable(const AgentPath* path,
     749             :     const IpAddress &prefix_ip,
     750             :     const uint32_t plen,
     751             :     const Peer *peer,
     752             :     const RouteParameters &params,
     753             :     InetUnicastAgentRouteTable *inet_table) {
     754           0 :     const NextHop *path_nh = path != NULL ? path->nexthop() : NULL;
     755           0 :     if (path_nh == NULL || inet_table == NULL || peer == NULL) {
     756           0 :         return;
     757             :     }
     758             : 
     759             : 
     760           0 :     DBRequest nh_req(DBRequest::DB_ENTRY_ADD_CHANGE);
     761           0 :     if (InitializeNhRequest(path_nh,
     762           0 :         nh_req, inet_table->vrf_entry()->GetName()) == false) {
     763           0 :         return;
     764             :     }
     765             : 
     766           0 :    std::string origin_vn = "";
     767           0 :     if (peer->GetType() == Peer::VXLAN_BGP_PEER) {
     768             :     } else {
     769           0 :         origin_vn = GetOriginVn(inet_table->vrf_entry(), prefix_ip, plen);
     770             :     }
     771           0 :     AdvertiseLocalRoute(prefix_ip, plen, nh_req, peer, params,
     772             :         inet_table, origin_vn);
     773           0 : }
     774             : 
     775             : 
     776           0 : void VxlanRoutingManager::PrintEvpnTable(const VrfEntry* const_vrf) {
     777           0 :     if (const_vrf == NULL) {
     778             :         std::cout<< "VxlanRoutingManager::PrintEvpnTable"
     779           0 :                  << ", NULL vrf ptr"
     780           0 :                  << std::endl;
     781           0 :         return;
     782             :     }
     783           0 :     VrfEntry* routing_vrf = const_cast<VrfEntry*>(const_vrf);
     784           0 :     EvpnAgentRouteTable *evpn_table = dynamic_cast<EvpnAgentRouteTable *>
     785           0 :         (routing_vrf->GetEvpnRouteTable());
     786           0 :     if (evpn_table == NULL) {
     787             :         std::cout<< "VxlanRoutingManager::PrintEvpnTable"
     788           0 :                  << ", NULL EVPN tbl ptr"
     789           0 :                  << std::endl;
     790           0 :         return;
     791             :     }
     792           0 :     EvpnRouteEntry *c_entry = dynamic_cast<EvpnRouteEntry *>
     793           0 :         (evpn_table->GetTablePartition(0)->GetFirst());
     794           0 :     if (c_entry) {
     795           0 :         if (c_entry->IsType5())
     796           0 :             std::cout << "Evpn Type 5 table:" << std::endl;
     797             :         else
     798           0 :             std::cout << "Evpn Type 2 table:" << std::endl;
     799             :     }
     800           0 :     while (c_entry) {
     801           0 :         const Route::PathList & path_list = c_entry->GetPathList();
     802           0 :         std::cout<< "  IP:" << c_entry->prefix_address()
     803           0 :                  << ", path count = " << path_list.size()
     804           0 :                  << ", ethernet_tag = " << c_entry->ethernet_tag()
     805           0 :                  << std::endl;
     806           0 :         for (Route::PathList::const_iterator it = path_list.begin();
     807           0 :             it != path_list.end(); ++it) {
     808             :             const AgentPath* path =
     809           0 :                 dynamic_cast<const AgentPath*>(it.operator->());
     810           0 :             if (!path)
     811           0 :                 continue;
     812             :             std::cout<< "    NH: "
     813           0 :                         << (path->nexthop() ? path->nexthop()->ToString() :
     814             :                         "NULL")
     815             :                         << ", " << "Peer:"
     816           0 :                         << (path->peer() ? path->peer()->GetName() : "NULL")
     817           0 :                         << std::endl;
     818           0 :             if (path->nexthop()->GetType() == NextHop::COMPOSITE) {
     819           0 :                 CompositeNH *comp_nh = dynamic_cast<CompositeNH *>
     820           0 :                     (path->nexthop());
     821           0 :                 std::cout<< "    n components="
     822           0 :                             << comp_nh->ComponentNHCount()
     823           0 :                             << std::endl;
     824             :             }
     825             :         }
     826           0 :         if (evpn_table && evpn_table->GetTablePartition(0))
     827           0 :             c_entry = dynamic_cast<EvpnRouteEntry *>
     828           0 :                 (evpn_table->GetTablePartition(0)->GetNext(c_entry));
     829             :         else
     830           0 :             break;
     831             :     }
     832             : }
     833             : 
     834           0 : void VxlanRoutingManager::PrintInetTable(const VrfEntry* const_vrf) {
     835           0 :     if (const_vrf == NULL) {
     836             :         std::cout<< "VxlanRoutingManager::PrintInetTable"
     837           0 :                  << ", NULL vrf ptr"
     838           0 :                  << std::endl;
     839           0 :         return;
     840             :     }
     841           0 :     VrfEntry* routing_vrf = const_cast<VrfEntry*>(const_vrf);
     842             :     InetUnicastAgentRouteTable *inet_table =
     843           0 :         routing_vrf->GetInet4UnicastRouteTable();
     844           0 :     if (inet_table == NULL) {
     845             :         std::cout<< "VxlanRoutingManager::PrintInetTable"
     846           0 :                  << ", NULL Inet tbl ptr"
     847           0 :                  << std::endl;
     848           0 :         return;
     849             :     }
     850           0 :     InetUnicastRouteEntry *c_entry = dynamic_cast<InetUnicastRouteEntry *>
     851           0 :         (inet_table->GetTablePartition(0)->GetFirst());
     852           0 :     if (c_entry) {
     853           0 :             std::cout << "Inet table:" << std::endl;
     854             :     }
     855           0 :     while (c_entry) {
     856           0 :         const Route::PathList & path_list = c_entry->GetPathList();
     857           0 :         std::cout<< "  IP:" << c_entry->prefix_address()
     858           0 :                  << ", path count = " << path_list.size() << std::endl;
     859           0 :         for (Route::PathList::const_iterator it = path_list.begin();
     860           0 :             it != path_list.end(); ++it) {
     861             :             const AgentPath* path =
     862           0 :                 dynamic_cast<const AgentPath*>(it.operator->());
     863           0 :             if (!path)
     864           0 :                 continue;
     865             :             std::cout<< "    NH: "
     866           0 :                         << (path->nexthop() ? path->nexthop()->ToString() :
     867             :                         "NULL")
     868             :                         << ", " << "Peer:"
     869           0 :                         << (path->peer() ? path->peer()->GetName() : "NULL")
     870           0 :                         << ", nh ptr = " << path->nexthop()
     871           0 :                         << ", pt ptr = " << path
     872           0 :                         << 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           0 :         if (inet_table && inet_table->GetTablePartition(0))
     882           0 :             c_entry = dynamic_cast<InetUnicastRouteEntry *>
     883           0 :                 (inet_table->GetTablePartition(0)->GetNext(c_entry));
     884             :         else
     885           0 :             break;
     886             :     }
     887             : }
     888             : 
     889           0 : void VxlanRoutingManager::ListAttachedVns() {
     890           0 :     Agent *agent = Agent::GetInstance();
     891           0 :     if (agent == NULL) {
     892           0 :         std::cout<<"VxlanRoutingManager::ListAttachedVns agent == NULL"<<std::endl;
     893           0 :         return;
     894             :     }
     895           0 :     VxlanRoutingManager *vxlan_rt_mgr = agent->oper_db()->vxlan_routing_manager();
     896           0 :     if (vxlan_rt_mgr == NULL) {
     897           0 :         std::cout<<"VxlanRoutingManager::ListAttachedVns rt mgr = NULL"<<std::endl;
     898           0 :         return;
     899             :     }
     900           0 :     VxlanRoutingVrfMapper& vrf_mapper = vxlan_rt_mgr->vrf_mapper_;
     901           0 :     VxlanRoutingVrfMapper::LrVrfInfoMap& lr_vrf_info_map = vrf_mapper.lr_vrf_info_map_;
     902           0 :     for(VxlanRoutingVrfMapper::LrVrfInfoMap::iterator it = lr_vrf_info_map.begin();
     903           0 :         it != lr_vrf_info_map.end(); it++) {
     904             :             std::cout << "VxlanRoutingManager::ListAttachedVns, "
     905             :                       << "rt VRF = "
     906           0 :                       << (*it).second.routing_vrf_->GetName()
     907           0 :                       << std::endl;
     908             :             std::cout << "VxlanRoutingManager::ListAttachedVns, "
     909           0 :                       << "size = "
     910           0 :                       << (*it).second.bridge_vn_list_.size()
     911           0 :                       << std::endl;
     912             :             VxlanRoutingVrfMapper::RoutedVrfInfo::BridgeVnList &reg_br =
     913           0 :                 (*it).second.bridge_vn_list_;
     914           0 :             for(VxlanRoutingVrfMapper::RoutedVrfInfo::BridgeVnList::iterator it_br = reg_br.begin();
     915           0 :                 it_br != reg_br.end(); it_br++) {
     916           0 :                 if ((*it_br))
     917             :                 std::cout<< "VxlanRoutingManager::ListAttachedVns, "
     918           0 :                          << "br VN = " << (*it_br)->GetName()
     919           0 :                          << std::endl;
     920             :             }
     921             :     }
     922             : }
     923             : 
     924             : //
     925             : //END-OF-FILE
     926             : //

Generated by: LCOV version 1.14