LCOV - code coverage report
Current view: top level - bgp - bgp_xmpp_rtarget_manager.cc (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 0 154 0.0 %
Date: 2026-09-28 02:13:17 Functions: 0 23 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2016 Juniper Networks, Inc. All rights reserved.
       3             :  */
       4             : #include "bgp/bgp_xmpp_rtarget_manager.h"
       5             : 
       6             : #include <utility>
       7             : #include <vector>
       8             : 
       9             : #include <boost/foreach.hpp>
      10             : 
      11             : #include "bgp/ipeer.h"
      12             : #include "bgp/bgp_peer_types.h"
      13             : #include "bgp/bgp_server.h"
      14             : #include "bgp/bgp_xmpp_channel.h"
      15             : #include "routing-instance/routing_instance.h"
      16             : 
      17             : using std::make_pair;
      18             : using std::pair;
      19             : using std::string;
      20             : using std::vector;
      21             : 
      22           0 : BgpXmppRTargetManager::BgpXmppRTargetManager(BgpXmppChannel *bgp_xmpp_channel) :
      23           0 :         bgp_xmpp_channel_(bgp_xmpp_channel) {
      24           0 : }
      25             : 
      26           0 : BgpXmppRTargetManager::~BgpXmppRTargetManager() {
      27           0 : }
      28             : 
      29           0 : bool BgpXmppRTargetManager::IsSubscriptionEmpty() const {
      30           0 :     return bgp_xmpp_channel_->IsSubscriptionEmpty();
      31             : }
      32             : 
      33           0 : bool BgpXmppRTargetManager::IsSubscriptionGrStale(
      34             :         RoutingInstance *instance) const {
      35           0 :     return bgp_xmpp_channel_->IsSubscriptionGrStale(instance);
      36             : }
      37             : 
      38           0 : bool BgpXmppRTargetManager::IsSubscriptionLlgrStale(
      39             :         RoutingInstance *instance) const {
      40           0 :     return bgp_xmpp_channel_->IsSubscriptionLlgrStale(instance);
      41             : }
      42             : 
      43           0 : bool BgpXmppRTargetManager::delete_in_progress() const {
      44           0 :     return bgp_xmpp_channel_->delete_in_progress();
      45             : }
      46             : 
      47           0 : const IPeer *BgpXmppRTargetManager::Peer() const {
      48           0 :     return bgp_xmpp_channel_->Peer();
      49             : }
      50             : 
      51           0 : void BgpXmppRTargetManager::Enqueue(DBRequest *req) const {
      52             :     RoutingInstanceMgr *instance_mgr =
      53           0 :         bgp_xmpp_channel_->bgp_server()->routing_instance_mgr();
      54           0 :     RoutingInstance *master = instance_mgr->GetDefaultRoutingInstance();
      55           0 :     BgpTable *table = master->GetTable(Address::RTARGET);
      56           0 :     assert(table);
      57           0 :     table->Enqueue(req);
      58           0 : }
      59             : 
      60           0 : BgpAttrPtr BgpXmppRTargetManager::GetRouteTargetRouteAttr() const {
      61           0 :     BgpAttrSpec attrs;
      62           0 :     BgpAttrNextHop nexthop(bgp_xmpp_channel_->bgp_server()->bgp_identifier());
      63           0 :     attrs.push_back(&nexthop);
      64           0 :     BgpAttrOrigin origin(BgpAttrOrigin::IGP);
      65           0 :     attrs.push_back(&origin);
      66           0 :     return bgp_xmpp_channel_->bgp_server()->attr_db()->Locate(attrs);
      67           0 : }
      68             : 
      69           0 : int BgpXmppRTargetManager::local_autonomous_system() const {
      70           0 :     return bgp_xmpp_channel_->bgp_server()->local_autonomous_system();
      71             : }
      72             : 
      73             : const BgpXmppRTargetManager::RouteTargetList &
      74           0 : BgpXmppRTargetManager::GetSubscribedRTargets(RoutingInstance *instance) const {
      75           0 :     return bgp_xmpp_channel_->GetSubscribedRTargets(instance);
      76             : }
      77             : 
      78           0 : uint32_t BgpXmppRTargetManager::GetRTargetRouteFlag(
      79             :         const RouteTarget &rtarget) const {
      80             :     PublishedRTargetRoutes::const_iterator rt_loc =
      81           0 :         rtarget_routes_.find(rtarget);
      82           0 :     if (rt_loc == rtarget_routes_.end() || rt_loc->second.empty())
      83           0 :         return 0;
      84             : 
      85             :     // Route is [llgr-]stale only if it is stale for all instances in the set.
      86           0 :     uint32_t flags = BgpPath::Stale | BgpPath::LlgrStale;
      87           0 :     BOOST_FOREACH(RoutingInstance *routing_instance, rt_loc->second) {
      88           0 :         if (!IsSubscriptionGrStale(routing_instance))
      89           0 :             flags &= ~BgpPath::Stale;
      90           0 :         if (!IsSubscriptionLlgrStale(routing_instance))
      91           0 :             flags &= ~BgpPath::LlgrStale;
      92           0 :         if (!flags)
      93           0 :             break;
      94             :     }
      95             : 
      96           0 :     return flags;
      97             : }
      98             : 
      99           0 : void BgpXmppRTargetManager::RTargetRouteOp(as_t asn,
     100             :                                            const RouteTarget &rtarget,
     101             :                                            BgpAttrPtr attr, bool add_change,
     102             :                                            uint32_t flags) const {
     103           0 :     if (add_change && delete_in_progress())
     104           0 :         return;
     105             : 
     106           0 :     DBRequest req;
     107           0 :     RTargetPrefix rt_prefix(asn, rtarget);
     108           0 :     req.key.reset(new RTargetTable::RequestKey(rt_prefix, Peer()));
     109           0 :     if (add_change) {
     110             :         // Find correct rtarget route flags if not already known.
     111           0 :         if (!flags)
     112           0 :             flags = GetRTargetRouteFlag(rtarget);
     113           0 :         req.data.reset(new RTargetTable::RequestData(attr, flags, 0, 0, 0));
     114           0 :         req.oper = DBRequest::DB_ENTRY_ADD_CHANGE;
     115             :     } else {
     116           0 :         req.oper = DBRequest::DB_ENTRY_DELETE;
     117             :     }
     118           0 :     Enqueue(&req);
     119           0 : }
     120             : 
     121           0 : void BgpXmppRTargetManager::ASNUpdateCallback(as_t old_asn,
     122             :                                               as_t old_local_asn) const {
     123           0 :     if (local_autonomous_system() == (int)old_local_asn)
     124           0 :         return;
     125           0 :     if (IsSubscriptionEmpty())
     126           0 :         return;
     127             : 
     128             :     // Delete the route and add with new local ASN
     129           0 :     BgpAttrPtr attr = GetRouteTargetRouteAttr();
     130           0 :     for (PublishedRTargetRoutes::const_iterator it = rtarget_routes_.begin();
     131           0 :             it != rtarget_routes_.end(); it++) {
     132           0 :         RTargetRouteOp(old_local_asn, it->first, NULL, false);
     133           0 :         RTargetRouteOp(local_autonomous_system(), it->first, attr, true);
     134             :     }
     135           0 : }
     136             : 
     137           0 : void BgpXmppRTargetManager::AddNewRTargetRoute(RoutingInstance *rtinstance,
     138             :         const RouteTarget &rtarget, BgpAttrPtr attr) {
     139           0 :     PublishedRTargetRoutes::iterator rt_loc = rtarget_routes_.find(rtarget);
     140           0 :     if (rt_loc == rtarget_routes_.end()) {
     141             :         pair<PublishedRTargetRoutes::iterator, bool> ret =
     142           0 :             rtarget_routes_.insert(make_pair(rtarget, RoutingInstanceList()));
     143             : 
     144           0 :         rt_loc = ret.first;
     145             : 
     146             :         // Send rtarget route ADD
     147           0 :         RTargetRouteOp(local_autonomous_system(), rtarget, attr, true);
     148             :     }
     149           0 :     rt_loc->second.insert(rtinstance);
     150           0 : }
     151             : 
     152           0 : void BgpXmppRTargetManager::DeleteRTargetRoute(
     153             :         RoutingInstance *rtinstance, const RouteTarget &rtarget) {
     154           0 :     PublishedRTargetRoutes::iterator rt_loc = rtarget_routes_.find(rtarget);
     155           0 :     assert(rt_loc != rtarget_routes_.end());
     156           0 :     assert(rt_loc->second.erase(rtinstance));
     157           0 :     if (rt_loc->second.empty()) {
     158           0 :         rtarget_routes_.erase(rtarget);
     159             :         // Send rtarget route DELETE
     160           0 :         RTargetRouteOp(local_autonomous_system(), rtarget, NULL, false);
     161             :     }
     162           0 : }
     163             : 
     164           0 : void BgpXmppRTargetManager::RoutingInstanceCallback(
     165             :         RoutingInstance *rt_instance, RouteTargetList *targets) {
     166             :     // Import list in the routing instance
     167           0 :     const RouteTargetList &new_list = rt_instance->GetImportList();
     168             : 
     169             :     // Previous route target list for which the rtarget route was added
     170           0 :     RouteTargetList *current = targets;
     171           0 :     RouteTargetList::iterator cur_next_it, cur_it;
     172           0 :     cur_it = cur_next_it = current->begin();
     173           0 :     RouteTargetList::const_iterator new_it = new_list.begin();
     174             : 
     175           0 :     pair<RouteTargetList::iterator, bool> r;
     176           0 :     BgpAttrPtr attr = GetRouteTargetRouteAttr();
     177           0 :     while (cur_it != current->end() && new_it != new_list.end()) {
     178           0 :         if (*new_it < *cur_it) {
     179           0 :             r = current->insert(*new_it);
     180           0 :             assert(r.second);
     181           0 :             AddNewRTargetRoute(rt_instance, *new_it, attr);
     182           0 :             new_it++;
     183           0 :         } else if (*new_it > *cur_it) {
     184           0 :             cur_next_it++;
     185           0 :             DeleteRTargetRoute(rt_instance, *cur_it);
     186           0 :             current->erase(cur_it);
     187           0 :             cur_it = cur_next_it;
     188             :         } else {
     189             :             // Update
     190           0 :             cur_it++;
     191           0 :             new_it++;
     192             :         }
     193           0 :         cur_next_it = cur_it;
     194             :     }
     195           0 :     for (; new_it != new_list.end(); ++new_it) {
     196           0 :         r = current->insert(*new_it);
     197           0 :         assert(r.second);
     198           0 :         AddNewRTargetRoute(rt_instance, *new_it, attr);
     199             :     }
     200           0 :     for (cur_next_it = cur_it;
     201           0 :          cur_it != current->end();
     202           0 :          cur_it = cur_next_it) {
     203           0 :         cur_next_it++;
     204           0 :         DeleteRTargetRoute(rt_instance, *cur_it);
     205           0 :         current->erase(cur_it);
     206             :     }
     207           0 : }
     208             : 
     209           0 : void BgpXmppRTargetManager::UpdateRouteTargetRouteFlag(
     210             :         RoutingInstance *routing_instance, const RouteTargetList &targets,
     211             :         uint32_t flags) const {
     212           0 :     BgpAttrPtr attr = GetRouteTargetRouteAttr();
     213           0 :     BOOST_FOREACH(RouteTarget rtarget, targets) {
     214             :         // Update route target route [llgr-]stale flag status.
     215           0 :         RTargetRouteOp(local_autonomous_system(), rtarget, attr, true, flags);
     216             :     }
     217           0 : }
     218             : 
     219           0 : void BgpXmppRTargetManager::Close() {
     220           0 :     if (rtarget_routes_.empty())
     221           0 :         return;
     222             : 
     223           0 :     for (PublishedRTargetRoutes::iterator it = rtarget_routes_.begin();
     224           0 :             it != rtarget_routes_.end(); it++) {
     225           0 :         RTargetRouteOp(local_autonomous_system(), it->first, NULL, false);
     226             :     }
     227           0 :     rtarget_routes_.clear();
     228             : }
     229             : 
     230           0 : void BgpXmppRTargetManager::Stale(const RouteTargetList &targets) const {
     231           0 :     BgpAttrPtr attr = GetRouteTargetRouteAttr();
     232             : 
     233             :     // Update route targets to clear STALE flag.
     234           0 :     BOOST_FOREACH(RouteTarget rtarget, targets) {
     235             :         PublishedRTargetRoutes::const_iterator rt_loc =
     236           0 :             rtarget_routes_.find(rtarget);
     237           0 :         assert(rt_loc != rtarget_routes_.end());
     238             : 
     239             :         // Send rtarget route ADD
     240           0 :         RTargetRouteOp(local_autonomous_system(), rtarget, attr, true);
     241             :     }
     242           0 : }
     243             : 
     244             : // Add/Delete rtarget route for import route target of the routing instance.
     245           0 : void BgpXmppRTargetManager::PublishRTargetRoute(RoutingInstance *rt_instance,
     246             :                                                 bool add_change) {
     247           0 :     if (IsSubscriptionEmpty())
     248           0 :         return;
     249             : 
     250           0 :     if (add_change) {
     251           0 :         BOOST_FOREACH(RouteTarget rtarget, GetSubscribedRTargets(rt_instance)) {
     252           0 :             AddNewRTargetRoute(rt_instance, rtarget, GetRouteTargetRouteAttr());
     253             :         }
     254             :     } else {
     255           0 :         BOOST_FOREACH(RouteTarget rtarget, GetSubscribedRTargets(rt_instance)) {
     256           0 :             DeleteRTargetRoute(rt_instance, rtarget);
     257             :         }
     258             :     }
     259             : }
     260             : 
     261           0 : void BgpXmppRTargetManager::FillInfo(BgpNeighborRoutingInstance *instance,
     262             :                                      const RouteTargetList &targets) const {
     263           0 :     vector<string> import_targets;
     264           0 :     BOOST_FOREACH(RouteTarget rt, targets) {
     265           0 :         import_targets.push_back(rt.ToString());
     266             :     }
     267           0 :     instance->set_import_targets(import_targets);
     268           0 : }

Generated by: LCOV version 1.14