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: 41 41 100.0 %
Date: 2026-06-11 01:56:02 Functions: 17 17 100.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.14