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: 179 312 57.4 %
Date: 2026-09-28 02:13:17 Functions: 19 39 48.7 %
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           0 : void VpnRouteState::AddRouteTarget(RTargetGroupMgr *mgr, int part_id,
      25             :     BgpRoute *rt, RTargetList::const_iterator it) {
      26           0 :     pair<RTargetList::iterator, bool> result;
      27           0 :     result = list_.insert(*it);
      28           0 :     assert(result.second);
      29           0 :     RtGroup *rtgroup = mgr->LocateRtGroup(*it);
      30           0 :     rtgroup->AddDepRoute(part_id, rt);
      31           0 : }
      32             : 
      33           0 : void VpnRouteState::DeleteRouteTarget(RTargetGroupMgr *mgr, int part_id,
      34             :     BgpRoute *rt, RTargetList::const_iterator it) {
      35           0 :     RtGroup *rtgroup = mgr->GetRtGroup(*it);
      36           0 :     rtgroup->RemoveDepRoute(part_id, rt);
      37           0 :     mgr->RemoveRtGroup(*it);
      38           0 :     list_.erase(it);
      39           0 : }
      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         378 : RTargetGroupMgr::RTargetGroupMgr(BgpServer *server) : server_(server),
      58         756 :     rtarget_route_trigger_(new TaskTrigger(
      59             :            boost::bind(&RTargetGroupMgr::ProcessRTargetRouteList, this),
      60         756 :            TaskScheduler::GetInstance()->GetTaskId("bgp::RTFilter"), 0)),
      61         756 :     remove_rtgroup_trigger_(new TaskTrigger(
      62             :            boost::bind(&RTargetGroupMgr::ProcessRtGroupList, this),
      63         756 :            TaskScheduler::GetInstance()->GetTaskId("bgp::RTFilter"), 0)),
      64         378 :     rtarget_trigger_lists_(DB::PartitionCount()),
      65        1134 :     master_instance_delete_ref_(this, NULL) {
      66        1890 :     for (int i = 0; i < DB::PartitionCount(); i++) {
      67        4536 :         rtarget_dep_triggers_.push_back(boost::shared_ptr<TaskTrigger>(new
      68             :                TaskTrigger(boost::bind(&RTargetGroupMgr::ProcessRouteTargetList,
      69             :                                        this, i),
      70        3024 :                TaskScheduler::GetInstance()->GetTaskId("db::DBTable"), i)));
      71             :     }
      72         378 : }
      73             : 
      74         268 : void RTargetGroupMgr::RTargetPeerSync(BgpTable *table, RTargetRoute *rt,
      75             :     DBTableBase::ListenerId id, RTargetState *dbstate,
      76             :     const RtGroup::InterestedPeerList *future) {
      77         268 :     CHECK_CONCURRENCY("bgp::RTFilter");
      78             : 
      79         268 :     RouteTarget rtarget = rt->GetPrefix().rtarget();
      80         268 :     RtGroup *rtgroup = LocateRtGroup(rtarget);
      81         268 :     assert(rtgroup);
      82             : 
      83         268 :     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         268 :     if (dbstate->GetList()->empty()) {
      90         268 :         rt->ClearState(table, id);
      91         268 :         delete dbstate;
      92         268 :         RemoveRtGroup(rtarget);
      93             :     }
      94         268 : }
      95             : 
      96         268 : void RTargetGroupMgr::BuildRTargetDistributionGraph(BgpTable *table,
      97             :     RTargetRoute *rt, DBTableBase::ListenerId id) {
      98         268 :     CHECK_CONCURRENCY("bgp::RTFilter");
      99             : 
     100             :     RTargetState *dbstate =
     101         268 :         static_cast<RTargetState *>(rt->GetState(table, id));
     102             : 
     103         268 :     RtGroup::InterestedPeerList peer_list;
     104             : 
     105         536 :     if (rt->IsDeleted() || !rt->BestPath() ||
     106         268 :         !rt->BestPath()->IsFeasible()) {
     107           0 :         RTargetPeerSync(table, rt, id, dbstate, &peer_list);
     108           0 :         return;
     109             :     }
     110             : 
     111         268 :     const BgpPath *best_ebgp_path = NULL;
     112         536 :     for (Route::PathList::iterator it = rt->GetPathList().begin();
     113        1072 :          it != rt->GetPathList().end(); it++) {
     114         268 :         BgpPath *path = static_cast<BgpPath *>(it.operator->());
     115         268 :         if (!path->IsFeasible())
     116           0 :             break;
     117         268 :         if (!path->GetPeer() || path->GetPeer()->IsXmppPeer())
     118         268 :             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         268 :     RTargetPeerSync(table, rt, id, dbstate, &peer_list);
     137         268 : }
     138             : 
     139           0 : bool RTargetGroupMgr::ProcessRouteTargetList(int part_id) {
     140           0 :     CHECK_CONCURRENCY("db::DBTable");
     141             : 
     142           0 :     BOOST_FOREACH(const RouteTarget &rtarget, rtarget_trigger_lists_[part_id]) {
     143           0 :         RtGroup *rtgroup = GetRtGroup(rtarget);
     144           0 :         if (!rtgroup)
     145           0 :             continue;
     146           0 :         rtgroup->NotifyDepRoutes(part_id);
     147             :     }
     148             : 
     149           0 :     rtarget_trigger_lists_[part_id].clear();
     150           0 :     return true;
     151             : }
     152             : 
     153           0 : void RTargetGroupMgr::AddRouteTargetToLists(const RouteTarget &rtarget) {
     154           0 :     for (int idx = 0; idx < DB::PartitionCount(); ++idx) {
     155           0 :         rtarget_trigger_lists_[idx].insert(rtarget);
     156           0 :         rtarget_dep_triggers_[idx]->Set();
     157             :     }
     158           0 : }
     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         268 : bool RTargetGroupMgr::ProcessRTargetRouteList() {
     183         268 :     CHECK_CONCURRENCY("bgp::RTFilter");
     184             : 
     185         268 :     RoutingInstanceMgr *mgr = server()->routing_instance_mgr();
     186         268 :     RoutingInstance *master = mgr->GetDefaultRoutingInstance();
     187         268 :     BgpTable *table = master->GetTable(Address::RTARGET);
     188             : 
     189             :     // Get the Listener id
     190         268 :     DBTableBase::ListenerId id = GetListenerId(table);
     191             : 
     192         268 :     for (RTargetRouteTriggerList::iterator it = rtarget_route_list_.begin();
     193         536 :          it != rtarget_route_list_.end(); it++) {
     194         268 :         BuildRTargetDistributionGraph(table, *it, id);
     195             :     }
     196             : 
     197         268 :     rtarget_route_list_.clear();
     198         268 :     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         378 : void RTargetGroupMgr::Initialize() {
     214         378 :     assert(table_state_.empty());
     215         378 :     RoutingInstanceMgr *mgr = server()->routing_instance_mgr();
     216         378 :     RoutingInstance *master = mgr->GetDefaultRoutingInstance();
     217         378 :     assert(master);
     218             : 
     219         378 :     master_instance_delete_ref_.Reset(master->deleter());
     220             : 
     221         378 :     RoutingInstance::RouteTableList const table_list = master->GetTables();
     222             :     DBTableBase::ListenerId id;
     223         378 :     RtGroupMgrTableState *ts = NULL;
     224         378 :     for (RoutingInstance::RouteTableList::const_iterator it =
     225        4158 :          table_list.begin(); it != table_list.end(); ++it) {
     226        3402 :         if (!it->second->IsVpnTable()) continue;
     227             : 
     228        1890 :         BgpTable *vpntable = it->second;
     229        1890 :         id = vpntable->Register(
     230             :             boost::bind(&RTargetGroupMgr::VpnRouteNotify, this, _1, _2),
     231             :             "RTargetGroupMgr");
     232        1890 :         ts = new RtGroupMgrTableState(vpntable, id);
     233        1890 :         table_state_.insert(std::make_pair(vpntable, ts));
     234             :     }
     235             : 
     236         378 :     BgpTable *rttable = master->GetTable(Address::RTARGET);
     237         378 :     id = rttable->Register(
     238             :         boost::bind(&RTargetGroupMgr::RTargetRouteNotify, this, _1, _2),
     239             :         "RTargetGroupMgr");
     240         378 :     ts = new RtGroupMgrTableState(rttable, id);
     241         378 :     table_state_.insert(std::make_pair(rttable, ts));
     242         378 : }
     243             : 
     244         378 : void RTargetGroupMgr::ManagedDelete() {
     245         378 :     if (rtgroup_map_.empty()) remove_rtgroup_trigger_->Set();
     246         378 : }
     247             : 
     248             : void
     249          16 : RTargetGroupMgr::RTargetDepSync(DBTablePartBase *root, BgpRoute *rt,
     250             :                                 DBTableBase::ListenerId id,
     251             :                                 VpnRouteState *dbstate,
     252             :                                 const VpnRouteState::RTargetList *future) {
     253          16 :     CHECK_CONCURRENCY("db::DBTable");
     254             : 
     255          16 :     BgpTable *table = static_cast<BgpTable *>(root->parent());
     256          16 :     if (!dbstate) {
     257          16 :         dbstate = new VpnRouteState();
     258          16 :         rt->SetState(table, id, dbstate);
     259             :     }
     260             : 
     261          16 :     int part_id = root->index();
     262          16 :     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          16 :     if (dbstate->GetList()->empty()) {
     269          16 :         rt->ClearState(root->parent(), id);
     270          16 :         delete dbstate;
     271             :     }
     272          16 : }
     273             : 
     274         615 : DBTableBase::ListenerId RTargetGroupMgr::GetListenerId(BgpTable *table) {
     275         615 :     RtGroupMgrTableStateList::iterator loc = table_state_.find(table);
     276         615 :     assert(loc != table_state_.end());
     277         615 :     RtGroupMgrTableState *ts = loc->second;
     278         615 :     DBTableBase::ListenerId id = ts->GetListenerId();
     279         615 :     assert(id != DBTableBase::kInvalidId);
     280         615 :     return id;
     281             : }
     282             : 
     283          32 : bool RTargetGroupMgr::VpnRouteNotify(DBTablePartBase *root,
     284             :                                      DBEntryBase *entry) {
     285          32 :     CHECK_CONCURRENCY("db::DBTable");
     286             : 
     287          32 :     BgpTable *table = static_cast<BgpTable *>(root->parent());
     288          32 :     BgpRoute *rt = static_cast<BgpRoute *>(entry);
     289             :     // Get the Listener id
     290          32 :     DBTableBase::ListenerId id = GetListenerId(table);
     291             : 
     292             :     // Get the dbstate
     293             :     VpnRouteState *dbstate =
     294          32 :         static_cast<VpnRouteState *>(rt->GetState(table, id));
     295             : 
     296          32 :     VpnRouteState::RTargetList list;
     297             : 
     298          48 :     if (entry->IsDeleted() || !rt->BestPath() ||
     299          16 :         !rt->BestPath()->IsFeasible()) {
     300          16 :         if (!dbstate)
     301          16 :             return true;
     302           0 :         RTargetDepSync(root, rt, id, dbstate, &list);
     303           0 :         return true;
     304             :     }
     305             : 
     306          16 :     const BgpPath *path = rt->BestPath();
     307          16 :     const BgpAttr *attr = path->GetAttr();
     308          16 :     const ExtCommunity *ext_community = attr->ext_community();
     309             : 
     310          16 :     if (ext_community) {
     311             :         // Gather all Route Target
     312           0 :         BOOST_FOREACH(const ExtCommunity::ExtCommunityValue &comm,
     313             :                       ext_community->communities()) {
     314           0 :             if (ExtCommunity::is_route_target(comm)) {
     315           0 :                 list.insert(RouteTarget(comm));
     316             :             }
     317             :         }
     318             :     }
     319             : 
     320          16 :     RTargetDepSync(root, rt, id, dbstate, &list);
     321          16 :     return true;
     322          32 : }
     323             : 
     324         315 : bool RTargetGroupMgr::RTargetRouteNotify(DBTablePartBase *root,
     325             :                                          DBEntryBase *entry) {
     326         315 :     CHECK_CONCURRENCY("db::DBTable");
     327             : 
     328         315 :     BgpTable *table = static_cast<BgpTable *>(root->parent());
     329         315 :     RTargetRoute *rt = static_cast<RTargetRoute *>(entry);
     330             :     // Get the Listener id
     331         315 :     DBTableBase::ListenerId id = GetListenerId(table);
     332             : 
     333             :     // Get the dbstate
     334             :     RTargetState *dbstate =
     335         315 :         static_cast<RTargetState *>(rt->GetState(table, id));
     336             : 
     337         315 :     if (!dbstate) {
     338         315 :         if (rt->IsDeleted()) return true;
     339         268 :         dbstate = new RTargetState();
     340         268 :         rt->SetState(table, id, dbstate);
     341             :     }
     342         268 :     if (rtarget_route_list_.empty())
     343         268 :         rtarget_route_trigger_->Set();
     344         268 :     rtarget_route_list_.insert(rt);
     345         268 :     return true;
     346             : }
     347             : 
     348         756 : RTargetGroupMgr::~RTargetGroupMgr() {
     349         378 :     assert(rtgroup_map_.empty());
     350         756 : }
     351             : 
     352             : // Search a RtGroup
     353           0 : RtGroup *RTargetGroupMgr::GetRtGroup(const RouteTarget &rt) {
     354           0 :     std::scoped_lock lock(mutex_);
     355           0 :     RtGroupMap::iterator loc = rtgroup_map_.find(rt);
     356           0 :     if (loc != rtgroup_map_.end()) {
     357           0 :         return loc->second;
     358             :     }
     359           0 :     return NULL;
     360           0 : }
     361             : 
     362             : // Search a RtGroup
     363           0 : RtGroup *RTargetGroupMgr::GetRtGroup(const ExtCommunity::ExtCommunityValue
     364             :                                         &community) {
     365           0 :     RouteTarget rt(community);
     366           0 :     return GetRtGroup(rt);
     367             : }
     368             : 
     369         268 : RtGroup *RTargetGroupMgr::LocateRtGroup(const RouteTarget &rt) {
     370         268 :     std::scoped_lock lock(mutex_);
     371         268 :     RtGroupMap::iterator loc = rtgroup_map_.find(rt);
     372         268 :     RtGroup *group = (loc != rtgroup_map_.end()) ? loc->second : NULL;
     373         268 :     if (group == NULL) {
     374         268 :         group = new RtGroup(rt);
     375         268 :         rtgroup_map_.insert(rt, group);
     376             :     }
     377         268 :     return group;
     378         268 : }
     379             : 
     380           0 : void RTargetGroupMgr::NotifyRtGroupUnlocked(const RouteTarget &rt) {
     381           0 :     CHECK_CONCURRENCY("bgp::RTFilter", "bgp::Config", "bgp::ConfigHelper");
     382             : 
     383           0 :     AddRouteTargetToLists(rt);
     384           0 :     if (!rt.IsNull())
     385           0 :         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           0 : void RTargetGroupMgr::NotifyRtGroup(const RouteTarget &rt) {
     397           0 :     CHECK_CONCURRENCY("bgp::Config", "bgp::ConfigHelper");
     398           0 :     std::scoped_lock lock(mutex_);
     399           0 :     NotifyRtGroupUnlocked(rt);
     400           0 : }
     401             : 
     402         268 : void RTargetGroupMgr::RemoveRtGroup(const RouteTarget &rt) {
     403         268 :     std::scoped_lock lock(mutex_);
     404         268 :     RtGroupMap::iterator loc = rtgroup_map_.find(rt);
     405         268 :     RtGroup *rtgroup = (loc != rtgroup_map_.end()) ? loc->second : NULL;
     406         268 :     assert(rtgroup);
     407             : 
     408         268 :     rtgroup_remove_list_.insert(rtgroup);
     409         268 :     remove_rtgroup_trigger_->Set();
     410         268 : }
     411             : 
     412           0 : void RTargetGroupMgr::GetRibOutInterestedPeers(RibOut *ribout,
     413             :              const ExtCommunity *ext_community,
     414             :              const RibPeerSet &peerset, RibPeerSet *new_peerset) {
     415           0 :     RtGroupInterestedPeerSet peer_set;
     416           0 :     RtGroup *null_rtgroup = GetRtGroup(RouteTarget::null_rtarget);
     417           0 :     if (null_rtgroup) peer_set = null_rtgroup->GetInterestedPeers();
     418           0 :     BOOST_FOREACH(const ExtCommunity::ExtCommunityValue &comm,
     419             :                   ext_community->communities()) {
     420           0 :         if (ExtCommunity::is_route_target(comm)) {
     421           0 :             RtGroup *rtgroup = GetRtGroup(comm);
     422           0 :             if (!rtgroup) continue;
     423           0 :             peer_set |= rtgroup->GetInterestedPeers();
     424             :         }
     425             :     }
     426           0 :     RibOut::PeerIterator iter(ribout, peerset);
     427           0 :     while (iter.HasNext()) {
     428           0 :         int current_index = iter.index();
     429           0 :         IPeerUpdate *peer = iter.Next();
     430           0 :         BgpPeer *tmp = dynamic_cast<BgpPeer *>(peer);
     431           0 :         assert(tmp);
     432           0 :         if (tmp->IsFamilyNegotiated(Address::RTARGET)) {
     433           0 :             if (!peer_set.test(tmp->GetIndex())) {
     434           0 :                 new_peerset->reset(current_index);
     435             :             }
     436             :         }
     437             :     }
     438           0 : }
     439             : 
     440         646 : void RTargetGroupMgr::UnregisterTables() {
     441         646 :     CHECK_CONCURRENCY("bgp::RTFilter");
     442             : 
     443         646 :     if (rtgroup_map_.empty()) {
     444         646 :         RoutingInstanceMgr *mgr = server()->routing_instance_mgr();
     445         646 :         RoutingInstance *master = mgr->GetDefaultRoutingInstance();
     446         646 :         if (master && master->deleted()) {
     447         378 :             for (RtGroupMgrTableStateList::iterator it =
     448        3024 :                  table_state_.begin(), itnext; it != table_state_.end();
     449        2268 :                  it = itnext) {
     450        2268 :                 itnext = it;
     451        2268 :                 itnext++;
     452        2268 :                 RtGroupMgrTableState *ts = it->second;
     453        2268 :                 DBTableBase::ListenerId id = ts->GetListenerId();
     454        2268 :                 BgpTable *bgptable = it->first;
     455        2268 :                 bgptable->Unregister(id);
     456        2268 :                 table_state_.erase(it);
     457        2268 :                 delete ts;
     458             :             }
     459         378 :             master_instance_delete_ref_.Reset(NULL);
     460             :         }
     461             :     }
     462         646 : }
     463             : 
     464         646 : bool RTargetGroupMgr::ProcessRtGroupList() {
     465         646 :     CHECK_CONCURRENCY("bgp::RTFilter");
     466        1182 :     BOOST_FOREACH(RtGroup *rtgroup, rtgroup_remove_list_) {
     467         268 :         if (!rtgroup->MayDelete())
     468           0 :             continue;
     469         268 :         RouteTarget rt = rtgroup->rt();
     470         268 :         rtgroup_map_.erase(rt);
     471             :     }
     472         646 :     rtgroup_remove_list_.clear();
     473             : 
     474         646 :     if (rtgroup_map_.empty()) UnregisterTables();
     475             : 
     476         646 :     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        2268 : RtGroupMgrTableState::RtGroupMgrTableState(BgpTable *table,
     492        2268 :                                            DBTableBase::ListenerId id)
     493        2268 :     : id_(id), table_delete_ref_(this, table->deleter()) {
     494        2268 :     assert(table->deleter() != NULL);
     495        2268 : }
     496             : 
     497        2268 : RtGroupMgrTableState::~RtGroupMgrTableState() {
     498        2268 : }
     499             : 
     500         852 : void RtGroupMgrTableState::ManagedDelete() {
     501         852 : }

Generated by: LCOV version 1.14