LCOV - code coverage report
Current view: top level - bgp/routing-instance - rtarget_group_mgr.cc (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 248 312 79.5 %
Date: 2026-09-21 02:11:39 Functions: 28 39 71.8 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
       3             :  */
       4             : #include "bgp/routing-instance/rtarget_group_mgr.h"
       5             : 
       6             : #include <boost/foreach.hpp>
       7             : 
       8             : #include <utility>
       9             : 
      10             : #include "base/map_util.h"
      11             : #include "base/set_util.h"
      12             : #include "base/task_annotations.h"
      13             : #include "base/task_trigger.h"
      14             : #include "bgp/bgp_config.h"
      15             : #include "bgp/bgp_peer.h"
      16             : #include "bgp/bgp_ribout.h"
      17             : #include "bgp/bgp_server.h"
      18             : #include "bgp/bgp_table.h"
      19             : #include "bgp/routing-instance/routing_instance.h"
      20             : #include "bgp/rtarget/rtarget_route.h"
      21             : 
      22             : using std::pair;
      23             : 
      24         264 : void VpnRouteState::AddRouteTarget(RTargetGroupMgr *mgr, int part_id,
      25             :     BgpRoute *rt, RTargetList::const_iterator it) {
      26         264 :     pair<RTargetList::iterator, bool> result;
      27         264 :     result = list_.insert(*it);
      28         264 :     assert(result.second);
      29         264 :     RtGroup *rtgroup = mgr->LocateRtGroup(*it);
      30         264 :     rtgroup->AddDepRoute(part_id, rt);
      31         264 : }
      32             : 
      33         264 : void VpnRouteState::DeleteRouteTarget(RTargetGroupMgr *mgr, int part_id,
      34             :     BgpRoute *rt, RTargetList::const_iterator it) {
      35         264 :     RtGroup *rtgroup = mgr->GetRtGroup(*it);
      36         264 :     rtgroup->RemoveDepRoute(part_id, rt);
      37         264 :     mgr->RemoveRtGroup(*it);
      38         264 :     list_.erase(it);
      39         264 : }
      40             : 
      41           0 : void RTargetState::AddInterestedPeer(RTargetGroupMgr *mgr, RtGroup *rtgroup,
      42             :     RTargetRoute *rt, RtGroup::InterestedPeerList::const_iterator it) {
      43           0 :     pair<RtGroup::InterestedPeerList::iterator, bool> result;
      44           0 :     result = list_.insert(*it);
      45           0 :     assert(result.second);
      46           0 :     rtgroup->AddInterestedPeer(it->first, rt);
      47           0 :     mgr->NotifyRtGroupUnlocked(rtgroup->rt());
      48           0 : }
      49             : 
      50           0 : void RTargetState::DeleteInterestedPeer(RTargetGroupMgr *mgr, RtGroup *rtgroup,
      51             :     RTargetRoute *rt, RtGroup::InterestedPeerList::iterator it) {
      52           0 :     rtgroup->RemoveInterestedPeer(it->first, rt);
      53           0 :     mgr->NotifyRtGroupUnlocked(rtgroup->rt());
      54           0 :     list_.erase(it);
      55           0 : }
      56             : 
      57          32 : RTargetGroupMgr::RTargetGroupMgr(BgpServer *server) : server_(server),
      58          64 :     rtarget_route_trigger_(new TaskTrigger(
      59             :            boost::bind(&RTargetGroupMgr::ProcessRTargetRouteList, this),
      60          64 :            TaskScheduler::GetInstance()->GetTaskId("bgp::RTFilter"), 0)),
      61          64 :     remove_rtgroup_trigger_(new TaskTrigger(
      62             :            boost::bind(&RTargetGroupMgr::ProcessRtGroupList, this),
      63          64 :            TaskScheduler::GetInstance()->GetTaskId("bgp::RTFilter"), 0)),
      64          32 :     rtarget_trigger_lists_(DB::PartitionCount()),
      65          96 :     master_instance_delete_ref_(this, NULL) {
      66         160 :     for (int i = 0; i < DB::PartitionCount(); i++) {
      67         384 :         rtarget_dep_triggers_.push_back(boost::shared_ptr<TaskTrigger>(new
      68             :                TaskTrigger(boost::bind(&RTargetGroupMgr::ProcessRouteTargetList,
      69             :                                        this, i),
      70         256 :                TaskScheduler::GetInstance()->GetTaskId("db::DBTable"), i)));
      71             :     }
      72          32 : }
      73             : 
      74          32 : void RTargetGroupMgr::RTargetPeerSync(BgpTable *table, RTargetRoute *rt,
      75             :     DBTableBase::ListenerId id, RTargetState *dbstate,
      76             :     const RtGroup::InterestedPeerList *future) {
      77          32 :     CHECK_CONCURRENCY("bgp::RTFilter");
      78             : 
      79          32 :     RouteTarget rtarget = rt->GetPrefix().rtarget();
      80          32 :     RtGroup *rtgroup = LocateRtGroup(rtarget);
      81          32 :     assert(rtgroup);
      82             : 
      83          32 :     map_synchronize(dbstate->GetMutableList(), future,
      84             :         boost::bind(&RTargetState::AddInterestedPeer, dbstate, this, rtgroup,
      85             :             rt, _1),
      86             :         boost::bind(&RTargetState::DeleteInterestedPeer, dbstate, this, rtgroup,
      87             :             rt, _1));
      88             : 
      89          32 :     if (dbstate->GetList()->empty()) {
      90          32 :         rt->ClearState(table, id);
      91          32 :         delete dbstate;
      92          32 :         RemoveRtGroup(rtarget);
      93             :     }
      94          32 : }
      95             : 
      96          32 : void RTargetGroupMgr::BuildRTargetDistributionGraph(BgpTable *table,
      97             :     RTargetRoute *rt, DBTableBase::ListenerId id) {
      98          32 :     CHECK_CONCURRENCY("bgp::RTFilter");
      99             : 
     100             :     RTargetState *dbstate =
     101          32 :         static_cast<RTargetState *>(rt->GetState(table, id));
     102             : 
     103          32 :     RtGroup::InterestedPeerList peer_list;
     104             : 
     105          64 :     if (rt->IsDeleted() || !rt->BestPath() ||
     106          32 :         !rt->BestPath()->IsFeasible()) {
     107           0 :         RTargetPeerSync(table, rt, id, dbstate, &peer_list);
     108           0 :         return;
     109             :     }
     110             : 
     111          32 :     const BgpPath *best_ebgp_path = NULL;
     112          64 :     for (Route::PathList::iterator it = rt->GetPathList().begin();
     113         128 :          it != rt->GetPathList().end(); it++) {
     114          32 :         BgpPath *path = static_cast<BgpPath *>(it.operator->());
     115          32 :         if (!path->IsFeasible())
     116           0 :             break;
     117          32 :         if (!path->GetPeer() || path->GetPeer()->IsXmppPeer())
     118          32 :             continue;
     119             : 
     120           0 :         const BgpPeer *peer = static_cast<const BgpPeer *>(path->GetPeer());
     121           0 :         if (peer->PeerType() == BgpProto::EBGP) {
     122           0 :             if (!best_ebgp_path) {
     123           0 :                 best_ebgp_path = path;
     124           0 :             } else if (!best_ebgp_path->PathSameNeighborAs(*path)) {
     125           0 :                 continue;
     126             :             }
     127             :         }
     128             : 
     129             :         std::pair<RtGroup::InterestedPeerList::iterator, bool> ret =
     130           0 :             peer_list.insert(std::pair<const BgpPeer *,
     131           0 :                  RtGroup::RTargetRouteList>(peer, RtGroup::RTargetRouteList()));
     132           0 :         assert(ret.second);
     133           0 :         ret.first->second.insert(rt);
     134             :     }
     135             : 
     136          32 :     RTargetPeerSync(table, rt, id, dbstate, &peer_list);
     137          32 : }
     138             : 
     139         378 : bool RTargetGroupMgr::ProcessRouteTargetList(int part_id) {
     140         378 :     CHECK_CONCURRENCY("db::DBTable");
     141             : 
     142        1098 :     BOOST_FOREACH(const RouteTarget &rtarget, rtarget_trigger_lists_[part_id]) {
     143         354 :         RtGroup *rtgroup = GetRtGroup(rtarget);
     144         384 :         if (!rtgroup)
     145           0 :             continue;
     146         384 :         rtgroup->NotifyDepRoutes(part_id);
     147             :     }
     148             : 
     149         383 :     rtarget_trigger_lists_[part_id].clear();
     150         382 :     return true;
     151             : }
     152             : 
     153         480 : void RTargetGroupMgr::AddRouteTargetToLists(const RouteTarget &rtarget) {
     154        2400 :     for (int idx = 0; idx < DB::PartitionCount(); ++idx) {
     155        1920 :         rtarget_trigger_lists_[idx].insert(rtarget);
     156        1920 :         rtarget_dep_triggers_[idx]->Set();
     157             :     }
     158         480 : }
     159             : 
     160           0 : void RTargetGroupMgr::DisableRouteTargetProcessing() {
     161           0 :     for (int idx = 0; idx < DB::PartitionCount(); ++idx) {
     162           0 :         rtarget_dep_triggers_[idx]->set_disable();
     163             :     }
     164           0 : }
     165             : 
     166           0 : void RTargetGroupMgr::EnableRouteTargetProcessing() {
     167           0 :     for (int idx = 0; idx < DB::PartitionCount(); ++idx) {
     168           0 :         rtarget_dep_triggers_[idx]->set_enable();
     169             :     }
     170           0 : }
     171             : 
     172           0 : bool RTargetGroupMgr::IsRouteTargetOnList(const RouteTarget &rtarget) const {
     173           0 :     for (int idx = 0; idx < DB::PartitionCount(); ++idx) {
     174           0 :         if (rtarget_trigger_lists_[idx].find(rtarget) !=
     175           0 :             rtarget_trigger_lists_[idx].end()) {
     176           0 :             return true;
     177             :         }
     178             :     }
     179           0 :     return false;
     180             : }
     181             : 
     182          32 : bool RTargetGroupMgr::ProcessRTargetRouteList() {
     183          32 :     CHECK_CONCURRENCY("bgp::RTFilter");
     184             : 
     185          32 :     RoutingInstanceMgr *mgr = server()->routing_instance_mgr();
     186          32 :     RoutingInstance *master = mgr->GetDefaultRoutingInstance();
     187          32 :     BgpTable *table = master->GetTable(Address::RTARGET);
     188             : 
     189             :     // Get the Listener id
     190          32 :     DBTableBase::ListenerId id = GetListenerId(table);
     191             : 
     192          32 :     for (RTargetRouteTriggerList::iterator it = rtarget_route_list_.begin();
     193          64 :          it != rtarget_route_list_.end(); it++) {
     194          32 :         BuildRTargetDistributionGraph(table, *it, id);
     195             :     }
     196             : 
     197          32 :     rtarget_route_list_.clear();
     198          32 :     return true;
     199             : }
     200             : 
     201           0 : void RTargetGroupMgr::DisableRTargetRouteProcessing() {
     202           0 :     rtarget_route_trigger_->set_disable();
     203           0 : }
     204             : 
     205           0 : void RTargetGroupMgr::EnableRTargetRouteProcessing() {
     206           0 :     rtarget_route_trigger_->set_enable();
     207           0 : }
     208             : 
     209           0 : bool RTargetGroupMgr::IsRTargetRouteOnList(RTargetRoute *rt) const {
     210           0 :     return rtarget_route_list_.find(rt) != rtarget_route_list_.end();
     211             : }
     212             : 
     213          32 : void RTargetGroupMgr::Initialize() {
     214          32 :     assert(table_state_.empty());
     215          32 :     RoutingInstanceMgr *mgr = server()->routing_instance_mgr();
     216          32 :     RoutingInstance *master = mgr->GetDefaultRoutingInstance();
     217          32 :     assert(master);
     218             : 
     219          32 :     master_instance_delete_ref_.Reset(master->deleter());
     220             : 
     221          32 :     RoutingInstance::RouteTableList const table_list = master->GetTables();
     222             :     DBTableBase::ListenerId id;
     223          32 :     RtGroupMgrTableState *ts = NULL;
     224          32 :     for (RoutingInstance::RouteTableList::const_iterator it =
     225         352 :          table_list.begin(); it != table_list.end(); ++it) {
     226         288 :         if (!it->second->IsVpnTable()) continue;
     227             : 
     228         160 :         BgpTable *vpntable = it->second;
     229         160 :         id = vpntable->Register(
     230             :             boost::bind(&RTargetGroupMgr::VpnRouteNotify, this, _1, _2),
     231             :             "RTargetGroupMgr");
     232         160 :         ts = new RtGroupMgrTableState(vpntable, id);
     233         160 :         table_state_.insert(std::make_pair(vpntable, ts));
     234             :     }
     235             : 
     236          32 :     BgpTable *rttable = master->GetTable(Address::RTARGET);
     237          32 :     id = rttable->Register(
     238             :         boost::bind(&RTargetGroupMgr::RTargetRouteNotify, this, _1, _2),
     239             :         "RTargetGroupMgr");
     240          32 :     ts = new RtGroupMgrTableState(rttable, id);
     241          32 :     table_state_.insert(std::make_pair(rttable, ts));
     242          32 : }
     243             : 
     244          32 : void RTargetGroupMgr::ManagedDelete() {
     245          32 :     if (rtgroup_map_.empty()) remove_rtgroup_trigger_->Set();
     246          32 : }
     247             : 
     248             : void
     249         704 : RTargetGroupMgr::RTargetDepSync(DBTablePartBase *root, BgpRoute *rt,
     250             :                                 DBTableBase::ListenerId id,
     251             :                                 VpnRouteState *dbstate,
     252             :                                 const VpnRouteState::RTargetList *future) {
     253         704 :     CHECK_CONCURRENCY("db::DBTable");
     254             : 
     255         704 :     BgpTable *table = static_cast<BgpTable *>(root->parent());
     256         704 :     if (!dbstate) {
     257         256 :         dbstate = new VpnRouteState();
     258         256 :         rt->SetState(table, id, dbstate);
     259             :     }
     260             : 
     261         704 :     int part_id = root->index();
     262         704 :     set_synchronize(dbstate->GetMutableList(), future,
     263             :         boost::bind(
     264             :             &VpnRouteState::AddRouteTarget, dbstate, this, part_id, rt, _1),
     265             :         boost::bind(
     266             :             &VpnRouteState::DeleteRouteTarget, dbstate, this, part_id, rt, _1));
     267             : 
     268         704 :     if (dbstate->GetList()->empty()) {
     269         256 :         rt->ClearState(root->parent(), id);
     270         256 :         delete dbstate;
     271             :     }
     272         704 : }
     273             : 
     274         804 : DBTableBase::ListenerId RTargetGroupMgr::GetListenerId(BgpTable *table) {
     275         804 :     RtGroupMgrTableStateList::iterator loc = table_state_.find(table);
     276         804 :     assert(loc != table_state_.end());
     277         804 :     RtGroupMgrTableState *ts = loc->second;
     278         804 :     DBTableBase::ListenerId id = ts->GetListenerId();
     279         804 :     assert(id != DBTableBase::kInvalidId);
     280         804 :     return id;
     281             : }
     282             : 
     283         708 : bool RTargetGroupMgr::VpnRouteNotify(DBTablePartBase *root,
     284             :                                      DBEntryBase *entry) {
     285         708 :     CHECK_CONCURRENCY("db::DBTable");
     286             : 
     287         708 :     BgpTable *table = static_cast<BgpTable *>(root->parent());
     288         708 :     BgpRoute *rt = static_cast<BgpRoute *>(entry);
     289             :     // Get the Listener id
     290         708 :     DBTableBase::ListenerId id = GetListenerId(table);
     291             : 
     292             :     // Get the dbstate
     293             :     VpnRouteState *dbstate =
     294         708 :         static_cast<VpnRouteState *>(rt->GetState(table, id));
     295             : 
     296         708 :     VpnRouteState::RTargetList list;
     297             : 
     298        1160 :     if (entry->IsDeleted() || !rt->BestPath() ||
     299         452 :         !rt->BestPath()->IsFeasible()) {
     300         260 :         if (!dbstate)
     301           4 :             return true;
     302         256 :         RTargetDepSync(root, rt, id, dbstate, &list);
     303         256 :         return true;
     304             :     }
     305             : 
     306         448 :     const BgpPath *path = rt->BestPath();
     307         448 :     const BgpAttr *attr = path->GetAttr();
     308         448 :     const ExtCommunity *ext_community = attr->ext_community();
     309             : 
     310         448 :     if (ext_community) {
     311             :         // Gather all Route Target
     312        1808 :         BOOST_FOREACH(const ExtCommunity::ExtCommunityValue &comm,
     313             :                       ext_community->communities()) {
     314         680 :             if (ExtCommunity::is_route_target(comm)) {
     315         456 :                 list.insert(RouteTarget(comm));
     316             :             }
     317             :         }
     318             :     }
     319             : 
     320         448 :     RTargetDepSync(root, rt, id, dbstate, &list);
     321         448 :     return true;
     322         708 : }
     323             : 
     324          64 : bool RTargetGroupMgr::RTargetRouteNotify(DBTablePartBase *root,
     325             :                                          DBEntryBase *entry) {
     326          64 :     CHECK_CONCURRENCY("db::DBTable");
     327             : 
     328          64 :     BgpTable *table = static_cast<BgpTable *>(root->parent());
     329          64 :     RTargetRoute *rt = static_cast<RTargetRoute *>(entry);
     330             :     // Get the Listener id
     331          64 :     DBTableBase::ListenerId id = GetListenerId(table);
     332             : 
     333             :     // Get the dbstate
     334             :     RTargetState *dbstate =
     335          64 :         static_cast<RTargetState *>(rt->GetState(table, id));
     336             : 
     337          64 :     if (!dbstate) {
     338          64 :         if (rt->IsDeleted()) return true;
     339          32 :         dbstate = new RTargetState();
     340          32 :         rt->SetState(table, id, dbstate);
     341             :     }
     342          32 :     if (rtarget_route_list_.empty())
     343          32 :         rtarget_route_trigger_->Set();
     344          32 :     rtarget_route_list_.insert(rt);
     345          32 :     return true;
     346             : }
     347             : 
     348          64 : RTargetGroupMgr::~RTargetGroupMgr() {
     349          32 :     assert(rtgroup_map_.empty());
     350          64 : }
     351             : 
     352             : // Search a RtGroup
     353        3561 : RtGroup *RTargetGroupMgr::GetRtGroup(const RouteTarget &rt) {
     354        3561 :     std::scoped_lock lock(mutex_);
     355        3592 :     RtGroupMap::iterator loc = rtgroup_map_.find(rt);
     356        3592 :     if (loc != rtgroup_map_.end()) {
     357        3297 :         return loc->second;
     358             :     }
     359         295 :     return NULL;
     360        3592 : }
     361             : 
     362             : // Search a RtGroup
     363         729 : RtGroup *RTargetGroupMgr::GetRtGroup(const ExtCommunity::ExtCommunityValue
     364             :                                         &community) {
     365         729 :     RouteTarget rt(community);
     366        1458 :     return GetRtGroup(rt);
     367             : }
     368             : 
     369        2213 : RtGroup *RTargetGroupMgr::LocateRtGroup(const RouteTarget &rt) {
     370        2213 :     std::scoped_lock lock(mutex_);
     371        2216 :     RtGroupMap::iterator loc = rtgroup_map_.find(rt);
     372        2214 :     RtGroup *group = (loc != rtgroup_map_.end()) ? loc->second : NULL;
     373        2214 :     if (group == NULL) {
     374         256 :         group = new RtGroup(rt);
     375         256 :         rtgroup_map_.insert(rt, group);
     376             :     }
     377        2216 :     return group;
     378        2214 : }
     379             : 
     380         480 : void RTargetGroupMgr::NotifyRtGroupUnlocked(const RouteTarget &rt) {
     381         480 :     CHECK_CONCURRENCY("bgp::RTFilter", "bgp::Config", "bgp::ConfigHelper");
     382             : 
     383         480 :     AddRouteTargetToLists(rt);
     384         480 :     if (!rt.IsNull())
     385         480 :         return;
     386             : 
     387           0 :     for (RtGroupMgrTableStateList::iterator it = table_state_.begin();
     388           0 :          it != table_state_.end(); ++it) {
     389           0 :         BgpTable *table = it->first;
     390           0 :         if (!table->IsVpnTable())
     391           0 :             continue;
     392           0 :         table->NotifyAllEntries();
     393             :     }
     394             : }
     395             : 
     396         480 : void RTargetGroupMgr::NotifyRtGroup(const RouteTarget &rt) {
     397         480 :     CHECK_CONCURRENCY("bgp::Config", "bgp::ConfigHelper");
     398         480 :     std::scoped_lock lock(mutex_);
     399         480 :     NotifyRtGroupUnlocked(rt);
     400         480 : }
     401             : 
     402        1416 : void RTargetGroupMgr::RemoveRtGroup(const RouteTarget &rt) {
     403        1416 :     std::scoped_lock lock(mutex_);
     404        1416 :     RtGroupMap::iterator loc = rtgroup_map_.find(rt);
     405        1416 :     RtGroup *rtgroup = (loc != rtgroup_map_.end()) ? loc->second : NULL;
     406        1416 :     assert(rtgroup);
     407             : 
     408        1416 :     rtgroup_remove_list_.insert(rtgroup);
     409        1416 :     remove_rtgroup_trigger_->Set();
     410        1416 : }
     411             : 
     412         295 : void RTargetGroupMgr::GetRibOutInterestedPeers(RibOut *ribout,
     413             :              const ExtCommunity *ext_community,
     414             :              const RibPeerSet &peerset, RibPeerSet *new_peerset) {
     415         295 :     RtGroupInterestedPeerSet peer_set;
     416         295 :     RtGroup *null_rtgroup = GetRtGroup(RouteTarget::null_rtarget);
     417         295 :     if (null_rtgroup) peer_set = null_rtgroup->GetInterestedPeers();
     418        1177 :     BOOST_FOREACH(const ExtCommunity::ExtCommunityValue &comm,
     419             :                   ext_community->communities()) {
     420         441 :         if (ExtCommunity::is_route_target(comm)) {
     421         301 :             RtGroup *rtgroup = GetRtGroup(comm);
     422         301 :             if (!rtgroup) continue;
     423         301 :             peer_set |= rtgroup->GetInterestedPeers();
     424             :         }
     425             :     }
     426         295 :     RibOut::PeerIterator iter(ribout, peerset);
     427         590 :     while (iter.HasNext()) {
     428         295 :         int current_index = iter.index();
     429         295 :         IPeerUpdate *peer = iter.Next();
     430         295 :         BgpPeer *tmp = dynamic_cast<BgpPeer *>(peer);
     431         295 :         assert(tmp);
     432         295 :         if (tmp->IsFamilyNegotiated(Address::RTARGET)) {
     433           0 :             if (!peer_set.test(tmp->GetIndex())) {
     434           0 :                 new_peerset->reset(current_index);
     435             :             }
     436             :         }
     437             :     }
     438         295 : }
     439             : 
     440          32 : void RTargetGroupMgr::UnregisterTables() {
     441          32 :     CHECK_CONCURRENCY("bgp::RTFilter");
     442             : 
     443          32 :     if (rtgroup_map_.empty()) {
     444          32 :         RoutingInstanceMgr *mgr = server()->routing_instance_mgr();
     445          32 :         RoutingInstance *master = mgr->GetDefaultRoutingInstance();
     446          32 :         if (master && master->deleted()) {
     447          32 :             for (RtGroupMgrTableStateList::iterator it =
     448         256 :                  table_state_.begin(), itnext; it != table_state_.end();
     449         192 :                  it = itnext) {
     450         192 :                 itnext = it;
     451         192 :                 itnext++;
     452         192 :                 RtGroupMgrTableState *ts = it->second;
     453         192 :                 DBTableBase::ListenerId id = ts->GetListenerId();
     454         192 :                 BgpTable *bgptable = it->first;
     455         192 :                 bgptable->Unregister(id);
     456         192 :                 table_state_.erase(it);
     457         192 :                 delete ts;
     458             :             }
     459          32 :             master_instance_delete_ref_.Reset(NULL);
     460             :         }
     461             :     }
     462          32 : }
     463             : 
     464         353 : bool RTargetGroupMgr::ProcessRtGroupList() {
     465         353 :     CHECK_CONCURRENCY("bgp::RTFilter");
     466        1391 :     BOOST_FOREACH(RtGroup *rtgroup, rtgroup_remove_list_) {
     467         519 :         if (!rtgroup->MayDelete())
     468         263 :             continue;
     469         256 :         RouteTarget rt = rtgroup->rt();
     470         256 :         rtgroup_map_.erase(rt);
     471             :     }
     472         353 :     rtgroup_remove_list_.clear();
     473             : 
     474         353 :     if (rtgroup_map_.empty()) UnregisterTables();
     475             : 
     476         353 :     return true;
     477             : }
     478             : 
     479           0 : void RTargetGroupMgr::DisableRtGroupProcessing() {
     480           0 :     remove_rtgroup_trigger_->set_disable();
     481           0 : }
     482             : 
     483           0 : void RTargetGroupMgr::EnableRtGroupProcessing() {
     484           0 :     remove_rtgroup_trigger_->set_enable();
     485           0 : }
     486             : 
     487           0 : bool RTargetGroupMgr::IsRtGroupOnList(RtGroup *rtgroup) const {
     488           0 :     return rtgroup_remove_list_.find(rtgroup) != rtgroup_remove_list_.end();
     489             : }
     490             : 
     491         192 : RtGroupMgrTableState::RtGroupMgrTableState(BgpTable *table,
     492         192 :                                            DBTableBase::ListenerId id)
     493         192 :     : id_(id), table_delete_ref_(this, table->deleter()) {
     494         192 :     assert(table->deleter() != NULL);
     495         192 : }
     496             : 
     497         192 : RtGroupMgrTableState::~RtGroupMgrTableState() {
     498         192 : }
     499             : 
     500         192 : void RtGroupMgrTableState::ManagedDelete() {
     501         192 : }

Generated by: LCOV version 1.14