LCOV - code coverage report
Current view: top level - bgp/routing-instance - routepath_replicator.h (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 45 45 100.0 %
Date: 2026-11-09 02:10:49 Functions: 21 21 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
       3             :  * Copyright Contributors to the OpenSDN project
       4             :  */
       5             : 
       6             : #ifndef SRC_BGP_ROUTING_INSTANCE_ROUTEPATH_REPLICATOR_H_
       7             : #define SRC_BGP_ROUTING_INSTANCE_ROUTEPATH_REPLICATOR_H_
       8             : 
       9             : #include <boost/ptr_container/ptr_map.hpp>
      10             : #include <sandesh/sandesh_trace.h>
      11             : 
      12             : #include <atomic>
      13             : #include <list>
      14             : #include <map>
      15             : #include <set>
      16             : #include <string>
      17             : #include <vector>
      18             : #include <mutex>
      19             : 
      20             : #include "base/lifetime.h"
      21             : #include "base/util.h"
      22             : #include "bgp/bgp_path.h"
      23             : #include "db/db_entry.h"
      24             : #include "db/db_table.h"
      25             : 
      26             : class BgpRoute;
      27             : class BgpServer;
      28             : class BgpTable;
      29             : class RtGroup;
      30             : class RoutePathReplicator;
      31             : class RouteTarget;
      32             : 
      33             : //
      34             : // This keeps track of a RoutePathReplicator's listener state for a BgpTable.
      35             : // An instance is created for each VRF table and for the VPN table.
      36             : //
      37             : // An entry for VPN table is created when RoutePathReplicator is initialized.
      38             : // An entry for a VRF table is created when processing a Join for the first
      39             : // export route target for the VRF.
      40             : // TableState is removed when a Bgp table is deleted.
      41             : // TableState takes a delete reference to the BgpTable and DeleteActor of the
      42             : // TableState manages the unregister of this listener from the BgpTable and
      43             : // delete of TableState object.
      44             : //
      45             : // A TableState entry keeps track of all the export route targets for a VRF
      46             : // by maintaining the GroupList. TableState cannot be deleted if GroupList
      47             : // is non-empty and table has replicated routes. Replicated routes are tracked
      48             : // using the DBStateCount of this listener
      49             : //
      50             : class TableState {
      51             : public:
      52             :     typedef std::set<RtGroup *> GroupList;
      53             : 
      54             :     TableState(RoutePathReplicator *replicator, BgpTable *table);
      55             :     ~TableState();
      56             : 
      57             :     void ManagedDelete();
      58             :     bool MayDelete() const;
      59             :     void RetryDelete();
      60             : 
      61             :     LifetimeActor *deleter();
      62             :     const LifetimeActor *deleter() const;
      63             :     bool deleted() const;
      64             : 
      65             :     void AddGroup(RtGroup *group);
      66             :     void RemoveGroup(RtGroup *group);
      67             :     const RtGroup *FindGroup(RtGroup *group) const;
      68           4 :     bool empty() const { return list_.empty(); }
      69             : 
      70             :     // Generation of the table's export route target list, bumped on every
      71             :     // change to it. Replication compares it against the value recorded in
      72             :     // RtReplicated to tell whether the paths replicated earlier still carry
      73             :     // the current targets. Written from the config tasks, read from
      74             :     // db::DBTable.
      75     4019852 :     uint64_t export_target_gen() const { return export_target_gen_.load(); }
      76      477304 :     void bump_export_target_gen() { ++export_target_gen_; }
      77             : 
      78     4633749 :     DBTableBase::ListenerId listener_id() const { return listener_id_; }
      79      254194 :     void set_listener_id(DBTableBase::ListenerId listener_id) {
      80      254194 :         assert(listener_id_ == DBTableBase::kInvalidId);
      81      254194 :         listener_id_ = listener_id;
      82      254194 :     }
      83             : 
      84             :     uint32_t route_count() const;
      85             : 
      86      508442 :     RoutePathReplicator *replicator() {
      87      508442 :         return replicator_;
      88             :     }
      89             : 
      90             :     const RoutePathReplicator *replicator() const {
      91             :         return replicator_;
      92             :     }
      93             : 
      94           2 :     BgpTable *table() const {
      95           2 :         return table_;
      96             :     }
      97             : 
      98      276828 :     BgpTable *table() {
      99      276828 :         return table_;
     100             :     }
     101             : 
     102      276928 :     const DBTable::DBTableWalkRef &walk_ref() const {
     103      276928 :         return walk_ref_;
     104             :     }
     105             : 
     106      356817 :     DBTable::DBTableWalkRef &walk_ref() {
     107      356817 :         return walk_ref_;
     108             :     }
     109             : 
     110       22603 :     void set_walk_ref(DBTable::DBTableWalkRef walk_ref) {
     111       22603 :         walk_ref_ = walk_ref;
     112       22603 :     }
     113             : 
     114             : private:
     115             :     class DeleteActor;
     116             :     RoutePathReplicator *replicator_;
     117             :     BgpTable *table_;
     118             :     DBTableBase::ListenerId listener_id_;
     119             :     boost::scoped_ptr<DeleteActor> deleter_;
     120             :     LifetimeRef<TableState> table_delete_ref_;
     121             :     GroupList list_;
     122             :     std::atomic<uint64_t> export_target_gen_;
     123             :     DBTable::DBTableWalkRef walk_ref_;
     124             : 
     125             :     DISALLOW_COPY_AND_ASSIGN(TableState);
     126             : };
     127             : 
     128             : //
     129             : // This keeps track of the replication state for a route in the primary table.
     130             : // The ReplicatedRtPathList is a set of SecondaryRouteInfo, where each element
     131             : // represents a secondary path in a secondary table. An entry is added to the
     132             : // set when a path is replicated to a secondary table removed when it's not
     133             : // replicated anymore.
     134             : //
     135             : // Changes to ReplicatedRtPathList may be triggered by changes in the primary
     136             : // route, changes in the export targets of the primary table or changes in the
     137             : // import targets of secondary tables.
     138             : //
     139             : // A RtReplicated is deleted when the route in the primary table is no longer
     140             : // replicated to any secondary tables.
     141             : //
     142             : class RtReplicated : public DBState {
     143             : public:
     144             :     struct SecondaryRouteInfo {
     145             :     public:
     146             :         BgpTable *table_;
     147             :         const IPeer *peer_;
     148             :         uint32_t path_id_;
     149             :         BgpPath::PathSource  src_;
     150             :         BgpRoute *rt_;
     151             : 
     152      956042 :         SecondaryRouteInfo(BgpTable *table, const IPeer *peer,
     153             :             uint32_t path_id, BgpPath::PathSource src, BgpRoute *rt)
     154      956042 :             : table_(table),
     155      956042 :               peer_(peer),
     156      956042 :               path_id_(path_id),
     157      956042 :               src_(src),
     158      956042 :               rt_(rt) {
     159      956042 :         }
     160     4027053 :         int CompareTo(const SecondaryRouteInfo &rhs) const {
     161     4027053 :             KEY_COMPARE(table_, rhs.table_);
     162     1025089 :             KEY_COMPARE(peer_, rhs.peer_);
     163      887273 :             KEY_COMPARE(path_id_, rhs.path_id_);
     164      876225 :             KEY_COMPARE(src_, rhs.src_);
     165      876225 :             KEY_COMPARE(rt_, rhs.rt_);
     166      874954 :             return 0;
     167             :         }
     168     3587633 :         bool operator<(const SecondaryRouteInfo &rhs) const {
     169     3587633 :             return (CompareTo(rhs) < 0);
     170             :         }
     171      440247 :         bool operator>(const SecondaryRouteInfo &rhs) const {
     172      440247 :             return (CompareTo(rhs) > 0);
     173             :         }
     174             : 
     175             :         std::string ToString() const;
     176             :     };
     177             : 
     178             :     typedef std::set<SecondaryRouteInfo> ReplicatedRtPathList;
     179             : 
     180             :     explicit RtReplicated(RoutePathReplicator *replicator);
     181             : 
     182             :     void AddRouteInfo(BgpTable *table, BgpRoute *rt,
     183             :         ReplicatedRtPathList::const_iterator it);
     184             :     void DeleteRouteInfo(BgpTable *table, BgpRoute *rt,
     185             :         ReplicatedRtPathList::const_iterator it);
     186             : 
     187     1447361 :     const ReplicatedRtPathList &GetList() const { return replicate_list_; }
     188     1446794 :     ReplicatedRtPathList *GetMutableList() { return &replicate_list_; }
     189             :     std::vector<std::string> GetTableNameList(const BgpPath *path) const;
     190             : 
     191             :     // TableState::export_target_gen of the primary table as of the last time
     192             :     // the route was replicated.
     193          86 :     uint64_t export_target_gen() const { return export_target_gen_; }
     194     1292334 :     void set_export_target_gen(uint64_t gen) { export_target_gen_ = gen; }
     195             : 
     196             : private:
     197             :     RoutePathReplicator *replicator_;
     198             :     ReplicatedRtPathList replicate_list_;
     199             :     uint64_t export_target_gen_;
     200             : };
     201             : 
     202             : //
     203             : // This class implements functionality to import and export BgpPaths between
     204             : // VRF BgpTables and a VPN BgpTable for a given address family. The exporting
     205             : // table is referred to as the primary table and the importing tables are
     206             : // referred to as secondary tables.
     207             : //
     208             : // The rules for importing and exporting paths are based on route targets of
     209             : // the VRF tables and the route targets in VPN routes. They can be summarized
     210             : // as follows:
     211             : //
     212             : // o The VPN table unconditionally imports routes from all VRF tables.
     213             : // o The VPN table potentially exports routes to all VRF tables.
     214             : // o A path in a VRF table is considered to have export targets of the table.
     215             : // o A path in the VPN table has route targets in it's attributes.
     216             : // o A path in a primary table is imported into a secondary table if one or
     217             : // o more of the targets for the path is in the list of import targets for
     218             : //   the secondary table.
     219             : // o Secondary paths are never exported to other secondary tables.
     220             : //
     221             : // Dependency tracking mechanisms are needed to implement replication in an
     222             : // an efficient manner. RoutePathReplicator does the following:
     223             : //
     224             : // 1. When an export target is added to or removed from a VRF table, walk all
     225             : //    routes in the VRF table to re-evaluate the new set of secondary paths.
     226             : //    The DBTableWalkMgr provides this functionality.
     227             : // 2. When an import target is added to or removed from a VRF table, walk all
     228             : //    VRF tables that have the target in question as an export target.  The
     229             : //    list of tables that export a target is maintained in the RTargetGroupMgr.
     230             : //    This list is updated by the replicator (by calling RTargetGroupMgr APIs)
     231             : //    based on configuration changes in the routing instance.
     232             : // 3. When an import target is added to or removed from a VRF tables, walk all
     233             : //    VPN routes with the target in question.  This dependency is maintained
     234             : //    by RTargetGroupMgr.
     235             : // 4. When a route is updated, calculate new set of secondary paths by going
     236             : //    through all VRF tables that import one of the targets for the route in
     237             : //    question.  The list of VRF tables is obtained from the RTargetGroupMgr.
     238             : // 5. When a route is updated, remove secondary paths that are not required
     239             : //    anymore.  The list of previous secondary paths for a primary route is
     240             : //    maintained using RtReplicated and reconciled/synchronized with the new
     241             : //    list obtained from 4.
     242             : //
     243             : // The TableStateList keeps track of the TableState for each VRF from which
     244             : // routes could be exported. It also has an entry for the TableState for the
     245             : // VPN table. This entry is created when the replicator is initialized and
     246             : // deleted during shutdown.
     247             : //
     248             : // The UnregTableList keeps track of tables for which we need to delete the
     249             : // TableState. Requests are enqueued from the db::DBTable task when a table
     250             : // walk finishes and the TableState is empty.
     251             : //
     252             : // A mutex is used to serialize access from multiple bgp::ConfigHelper tasks.
     253             : //
     254             : class RoutePathReplicator {
     255             : public:
     256             :     RoutePathReplicator(BgpServer *server, Address::Family family);
     257             :     virtual ~RoutePathReplicator();
     258             : 
     259             :     void Initialize();
     260             :     void Join(BgpTable *table, const RouteTarget &rt, bool import);
     261             :     void Leave(BgpTable *table, const RouteTarget &rt, bool import);
     262             : 
     263             :     std::vector<std::string> GetReplicatedTableNameList(const BgpTable *table,
     264             :         const BgpRoute *route, const BgpPath *path) const;
     265             :     const RtReplicated *GetReplicationState(BgpTable *table,
     266             :                                             BgpRoute *rt) const;
     267             : 
     268             : private:
     269             :     friend class ReplicationTest;
     270             :     friend class BGPaaSRDTest;
     271             :     friend class RtReplicated;
     272             :     friend class TableState;
     273             : 
     274             :     typedef std::map<BgpTable *, TableState *> TableStateList;
     275             :     typedef std::set<BgpTable *> UnregTableList;
     276             : 
     277             :     void RequestWalk(BgpTable *table);
     278             :     void BulkReplicationDone(DBTableBase *dbtable);
     279             :     bool UnregisterTables();
     280             : 
     281             :     TableState *AddTableState(BgpTable *table, RtGroup *group = NULL);
     282             :     void RemoveTableState(BgpTable *table, RtGroup *group);
     283             :     void DeleteTableState(BgpTable *table);
     284             :     void UnregisterTableState(BgpTable *table);
     285             :     TableState *FindTableState(BgpTable *table);
     286             :     const TableState *FindTableState(const BgpTable *table) const;
     287             : 
     288             :     void JoinVpnTable(RtGroup *group);
     289             :     void LeaveVpnTable(RtGroup *group);
     290             : 
     291             :     bool RouteListener(TableState *ts, DBTablePartBase *root,
     292             :                        DBEntryBase *entry);
     293             :     void DeleteSecondaryPath(BgpTable  *table, BgpRoute *rt,
     294             :                              const RtReplicated::SecondaryRouteInfo &rtinfo);
     295             :     void DBStateSync(BgpTable *table, TableState *ts, BgpRoute *rt,
     296             :                      RtReplicated *dbstate,
     297             :                      const RtReplicated::ReplicatedRtPathList *future);
     298             : 
     299     9075568 :     BgpServer *server() { return server_; }
     300     8056421 :     Address::Family family() const { return family_; }
     301             :     const BgpServer *server() const { return server_; }
     302             : 
     303             :     BgpServer *server_;
     304             :     std::mutex mutex_;
     305             :     TableStateList table_state_list_;
     306             :     Address::Family family_;
     307             :     BgpTable *vpn_table_;
     308             :     SandeshTraceBufferPtr trace_buf_;
     309             : 
     310             :     DISALLOW_COPY_AND_ASSIGN(RoutePathReplicator);
     311             : };
     312             : 
     313             : #endif  // SRC_BGP_ROUTING_INSTANCE_ROUTEPATH_REPLICATOR_H_

Generated by: LCOV version 1.14