LCOV - code coverage report
Current view: top level - vnsw/agent/oper - vxlan_templates.cc (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 0 146 0.0 %
Date: 2026-06-04 02:06:09 Functions: 0 6 0.0 %
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/bgp_as_service.h>
       8             : 
       9             : template <class ItType>
      10             : std::vector<IpAddress> VxlanRoutingManager::ItemNexthopsToVector(ItType *item) {
      11             :     std::vector<IpAddress> nh_addr;
      12             :     const uint32_t n_items = item->entry.next_hops.next_hop.size();
      13             :     for (uint32_t i_nh=0; i_nh < n_items; i_nh++) {
      14             :         const IpAddress nh_ip = IpAddress::from_string(
      15             :             item->entry.next_hops.next_hop[i_nh].address);
      16             :         nh_addr.insert(nh_addr.end(), nh_ip);
      17             :     }
      18             : 
      19             :     return nh_addr;
      20             : }
      21             : 
      22             : // A nexthop is counted as BGPaaS when it has MPLS label and this
      23             : // label points to the VmInterface linked with the BGPaaS object
      24           0 : static bool IsBgpaasInterfaceNexthop(const Agent* agent, const NextHop* nh) {
      25           0 :     if (nh->GetType() != NextHop::INTERFACE ||
      26           0 :         nh->mpls_label() == NULL) {
      27           0 :         return false;
      28             :     }
      29             : 
      30           0 :     const InterfaceNH *intf_nh = static_cast<const InterfaceNH *>(nh);
      31           0 :     const Interface *interface = intf_nh->GetInterface();
      32           0 :     if (interface->type() != Interface::VM_INTERFACE)
      33           0 :         return false;
      34             : 
      35             :     const VmInterface *vm_intf =
      36           0 :         dynamic_cast<const VmInterface*>(interface);
      37           0 :     const Ip4Address& intf_ip4 = vm_intf->primary_ip_addr();
      38           0 :     const Ip6Address& intf_ip6 = vm_intf->primary_ip6_addr();
      39             : 
      40           0 :     if (agent->oper_db()->bgp_as_a_service()->
      41           0 :         IsBgpService(vm_intf, IpAddress(intf_ip4), IpAddress(intf_ip4))) {
      42           0 :         return true;
      43             :     }
      44           0 :     if (agent->oper_db()->bgp_as_a_service()->
      45           0 :         IsBgpService(vm_intf, IpAddress(intf_ip6), IpAddress(intf_ip6))) {
      46           0 :         return true;
      47             :     }
      48           0 :     return false;
      49             : }
      50             : 
      51             : // A composite nexthop is counted as BGPaaS when at least one component is
      52             : // an interface
      53           0 : static bool IsBgpaasCompositeNexthop(const Agent* agent, const NextHop* nh) {
      54           0 :     if (nh->GetType() != NextHop::COMPOSITE)
      55           0 :     return false;
      56           0 :     const CompositeNH *composite_nh = dynamic_cast<const CompositeNH*>(nh);
      57           0 :     uint32_t n_comps = composite_nh->ComponentNHCount();
      58           0 :     for (uint32_t i=0; i < n_comps; i++) {
      59           0 :         const NextHop *c_nh = composite_nh->GetNH(i);
      60           0 :         if (c_nh != nullptr &&
      61           0 :             IsBgpaasInterfaceNexthop(agent, c_nh) == true) {
      62           0 :             return true;
      63             :         }
      64             :     }
      65           0 :     return false;
      66             : }
      67             : 
      68             : template<typename NhType>
      69           0 : void VxlanRoutingManager::AddBgpaasInterfaceComponentToList(
      70             :     const std::string& vrf_name,
      71             :     const NhType &nh_item,
      72             :     ComponentNHKeyList& comp_nh_list,
      73             :     std::vector<std::string> &peer_sources) {
      74             : 
      75           0 :     for (const auto &nexthop_addr : peer_sources) {
      76           0 :         const Agent *agent = Agent::GetInstance();
      77           0 :         IpAddress nh_ip;
      78             :         uint32_t prefix_len;
      79           0 :         boost::system::error_code ec;
      80             : 
      81           0 :         if (is_ipv4_string(nexthop_addr)) {
      82           0 :             nh_ip = Ip4Address::from_string(ipv4_prefix(nexthop_addr), ec);
      83           0 :             prefix_len = ipv4_prefix_len(nexthop_addr);
      84           0 :         } else if (is_ipv6_string(nexthop_addr)) {
      85           0 :             nh_ip = Ip6Address::from_string(ipv6_prefix(nexthop_addr), ec);
      86           0 :             prefix_len = ipv6_prefix_len(nexthop_addr);
      87             :         } else {
      88           0 :             LOG(ERROR, "Error in VxlanRoutingManager"
      89             :                 << "::AddBgpaasInterfaceComponentToList"
      90             :                 << ", nexthop_addr = " << nexthop_addr
      91             :                 << " is not an IPv4 or IPv6 prefix");
      92           0 :             return;
      93             :         }
      94           0 :         if (ec) {
      95           0 :             continue;
      96             :         }
      97             :         const AgentRoute *intf_rt =
      98           0 :             FindEvpnOrInetRoute(agent, vrf_name, nh_ip, prefix_len, nh_item);
      99             :         const AgentPath *loc_path =
     100           0 :             intf_rt->FindIntfOrCompLocalVmPortPath();
     101           0 :         if (loc_path == nullptr) {
     102           0 :             continue;
     103             :         }
     104           0 :         if (loc_path->nexthop() == nullptr) {
     105           0 :             continue;
     106             :         }
     107           0 :         if (IsBgpaasInterfaceNexthop(agent, loc_path->nexthop())) {
     108           0 :             DBEntryBase::KeyPtr key_ptr =
     109           0 :                 loc_path->nexthop()->GetDBRequestKey();
     110             :             NextHopKey *nh_key =
     111           0 :                 static_cast<NextHopKey *>(key_ptr.release());
     112           0 :             std::unique_ptr<const NextHopKey> nh_key_ptr(nh_key);
     113           0 :             ComponentNHKeyPtr component_nh_key(new
     114             :                                 ComponentNHKey(MplsTable::kInvalidLabel,
     115           0 :                                                std::move(nh_key_ptr)));
     116           0 :             comp_nh_list.push_back(component_nh_key);
     117           0 :         } else if (IsBgpaasCompositeNexthop(agent, loc_path->nexthop())) {
     118           0 :             CompositeNH *loc_comp_nh = dynamic_cast<CompositeNH*>
     119           0 :                 (loc_path->nexthop());
     120             : 
     121           0 :             DBEntryBase::KeyPtr key_ptr =
     122           0 :                 loc_comp_nh->GetDBRequestKey();
     123             :             CompositeNHKey *nh_key =
     124           0 :                 static_cast<CompositeNHKey *>(key_ptr.release());
     125           0 :             std::unique_ptr<const NextHopKey> nh_key_ptr(nh_key);
     126             : 
     127           0 :             if (nh_key == nullptr){
     128           0 :                 LOG(ERROR, "Error in VxlanRoutingManager::"
     129             :                 << "::AddBgpaasInterfaceComponentToList"
     130             :                 << ", null nh key");
     131             :             }
     132             : 
     133             :             const ComponentNHList& component_nh_list =
     134           0 :                 loc_comp_nh->component_nh_list();
     135           0 :             for (auto &component_nh : component_nh_list) {
     136           0 :                 std::unique_ptr<const NextHopKey> nh_key_ptr;
     137           0 :                 ComponentNHKeyPtr component_nh_key;
     138           0 :                 if (component_nh.get() == nullptr) {
     139             :                     // component_nh_key.reset(NULL);
     140             :                 } else {
     141           0 :                     DBEntryBase::KeyPtr key =
     142           0 :                         component_nh.get()->nh()->GetDBRequestKey();
     143             :                     NextHopKey *nh_key =
     144           0 :                         static_cast<NextHopKey *>(key.release());
     145           0 :                     nh_key_ptr.reset(nh_key);
     146           0 :                     component_nh_key.reset(
     147           0 :                         new ComponentNHKey(MplsTable::kInvalidLabel,
     148           0 :                                            std::move(nh_key_ptr)));
     149           0 :                 }
     150           0 :                 comp_nh_list.push_back(component_nh_key);
     151             :             }
     152           0 :         }
     153             :     }
     154             : }
     155             : 
     156             : template<typename NhType>
     157           0 : void VxlanRoutingManager::AddInterfaceComponentToList(
     158             :     const std::string& prefix_str,
     159             :     const std::string& vrf_name,
     160             :     const NhType &nh_item,
     161             :     ComponentNHKeyList& comp_nh_list,
     162             :     std::vector<std::string> &peer_sources) {
     163           0 :     const Agent *agent = Agent::GetInstance();
     164           0 :     IpAddress ip_addr;
     165             :     uint32_t prefix_len;
     166           0 :     boost::system::error_code ec;
     167             : 
     168           0 :     if (is_ipv4_string(prefix_str)) {
     169           0 :         ip_addr = Ip4Address::from_string(ipv4_prefix(prefix_str), ec);
     170           0 :         prefix_len = ipv4_prefix_len(prefix_str);
     171           0 :     } else if (is_ipv6_string(prefix_str)) {
     172           0 :         std::string addr_str = ipv6_prefix(prefix_str);
     173           0 :         prefix_len = ipv6_prefix_len(prefix_str);
     174           0 :         ip_addr = Ip6Address::from_string(addr_str, ec);
     175           0 :     } else {
     176           0 :         LOG(ERROR, "Error in VxlanRoutingManager::AddInterfaceComponentToList"
     177             :             << ", prefix_str = " << prefix_str
     178             :             << " is not an IPv4 or IPv6 prefix");
     179           0 :         return;
     180             :     }
     181             : 
     182           0 :     if (ec) {
     183           0 :         LOG(ERROR, "Possible error in "
     184             :             << "VxlanRoutingManager::AddInterfaceComponentToList"
     185             :             << ", cannot convert prefix_str = " << prefix_str
     186             :             << " to IPv4 or IPv6 address");
     187           0 :         return;
     188             :     }
     189             : 
     190             :     const AgentRoute *intf_rt =
     191           0 :         FindEvpnOrInetRoute(agent, vrf_name, ip_addr, prefix_len, nh_item);
     192           0 :     if (intf_rt == NULL) {
     193           0 :         AddBgpaasInterfaceComponentToList(vrf_name, nh_item, comp_nh_list,
     194             :                                           peer_sources);
     195           0 :         return;
     196             :     }
     197             : 
     198             :     const AgentPath *loc_path =
     199           0 :         intf_rt->FindIntfOrCompLocalVmPortPath();
     200           0 :     if (loc_path == NULL) {
     201           0 :         AddBgpaasInterfaceComponentToList(vrf_name, nh_item, comp_nh_list,
     202             :                                           peer_sources);
     203           0 :         return;
     204             :     }
     205           0 :     if (loc_path->nexthop() == NULL) {
     206           0 :         AddBgpaasInterfaceComponentToList(vrf_name, nh_item, comp_nh_list,
     207             :                                           peer_sources);
     208           0 :         return;
     209             :     }
     210             : 
     211             :     // Case 1. NextHop is an interface
     212           0 :     if (loc_path->nexthop()->GetType() == NextHop::INTERFACE) {
     213           0 :         DBEntryBase::KeyPtr key_ptr =
     214           0 :             loc_path->nexthop()->GetDBRequestKey();
     215             :         NextHopKey *nh_key =
     216           0 :             static_cast<NextHopKey *>(key_ptr.release());
     217           0 :         std::unique_ptr<const NextHopKey> nh_key_ptr(nh_key);
     218           0 :         ComponentNHKeyPtr component_nh_key(new ComponentNHKey(MplsTable::kInvalidLabel,  // label
     219           0 :                                         std::move(nh_key_ptr)));
     220           0 :         comp_nh_list.push_back(component_nh_key);
     221           0 :         return;
     222           0 :     }
     223             : 
     224             :     // Case 2. NextHop is a composite of interfaces
     225             :     // Copy all interfaces from this composite
     226             :     // into the components list
     227           0 :     if (loc_path->nexthop()->GetType() == NextHop::COMPOSITE) {
     228           0 :         CompositeNH *loc_comp_nh = dynamic_cast<CompositeNH*>
     229           0 :             (loc_path->nexthop());
     230             : 
     231           0 :         DBEntryBase::KeyPtr key_ptr =
     232           0 :             loc_comp_nh->GetDBRequestKey();
     233             :         CompositeNHKey *nh_key =
     234           0 :             static_cast<CompositeNHKey *>(key_ptr.release());
     235           0 :         std::unique_ptr<const NextHopKey> nh_key_ptr(nh_key);
     236             : 
     237           0 :         if (nh_key == NULL){
     238           0 :             LOG(ERROR, "Error in VxlanRoutingManager::AddInterfaceComponentToList"
     239             :             << ", null nh key");
     240           0 :             assert(nh_key != NULL);
     241             :         }
     242             : 
     243             :         // Refresh on path_preference.sequence change
     244             :         const ComponentNHList& component_nh_list =
     245           0 :             loc_comp_nh->component_nh_list();
     246           0 :         for (ComponentNHList::const_iterator
     247           0 :             it_nh = component_nh_list.begin();
     248           0 :             it_nh != component_nh_list.end(); it_nh++) {
     249             :             // nullptr means deleted component, which
     250             :             // can be reused later
     251           0 :             std::unique_ptr<const NextHopKey> nh_key_ptr;
     252           0 :             ComponentNHKeyPtr component_nh_key;
     253           0 :             if (it_nh->get() == NULL) {
     254             :                 // component_nh_key.reset(NULL);
     255             :             } else {
     256           0 :                 DBEntryBase::KeyPtr key =
     257           0 :                     it_nh->get()->nh()->GetDBRequestKey();
     258             :                 NextHopKey *nh_key =
     259           0 :                     static_cast<NextHopKey *>(key.release());
     260           0 :                 nh_key_ptr.reset(nh_key);
     261           0 :                 component_nh_key.reset(
     262           0 :                     new ComponentNHKey(MplsTable::kInvalidLabel, std::move(nh_key_ptr)));
     263           0 :             }
     264           0 :             comp_nh_list.push_back(component_nh_key);
     265             :         }
     266           0 :     }
     267             : }  // AddInterfaceComponentToList func
     268             : 
     269             : //
     270             : // END-OF-FILE
     271             : //

Generated by: LCOV version 1.14