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

Generated by: LCOV version 1.14