LCOV - code coverage report
Current view: top level - vnsw/agent/oper - agent_route.h (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 60 81 74.1 %
Date: 2026-11-09 02:10:49 Functions: 46 62 74.2 %
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 vnsw_agent_route_hpp
       7             : #define vnsw_agent_route_hpp
       8             : 
       9             : #include <sys/types.h>
      10             : #include <sys/socket.h>
      11             : #include <net/ethernet.h>
      12             : 
      13             : #include <base/address.h>
      14             : #include <base/lifetime.h>
      15             : #include <base/patricia.h>
      16             : #include <base/task_annotations.h>
      17             : 
      18             : #include <cmn/agent_cmn.h>
      19             : #include <cmn/agent.h>
      20             : #include <agent_types.h>
      21             : #include <route/route.h>
      22             : #include <route/table.h>
      23             : 
      24             : #include <oper/interface_common.h>
      25             : #include <oper/nexthop.h>
      26             : #include <oper/peer.h>
      27             : #include <oper/agent_types.h>
      28             : #include <oper/multicast.h>
      29             : #include <sandesh/sandesh_trace.h>
      30             : 
      31             : class AgentRoute;
      32             : class AgentPath;
      33             : class Peer;
      34             : class EcmpData;
      35             : 
      36             : struct AgentRouteKey : public AgentKey {
      37       20570 :     AgentRouteKey(const Peer *peer, const std::string &vrf_name) :
      38       20570 :         AgentKey(), peer_(peer), vrf_name_(vrf_name) { }
      39       20570 :     virtual ~AgentRouteKey() { }
      40             : 
      41             :     virtual Agent::RouteTableType GetRouteTableType() = 0;
      42             :     virtual std::string ToString() const = 0;
      43             :     virtual AgentRoute *AllocRouteEntry(VrfEntry *vrf,
      44             :                                         bool is_multicast) const = 0;
      45             :     virtual AgentRouteKey *Clone() const = 0;
      46             : 
      47       40176 :     const std::string &vrf_name() const { return vrf_name_; }
      48       67900 :     const Peer *peer() const { return peer_.get(); }
      49        2011 :     void set_peer(const Peer *peer) {peer_ = peer;}
      50             : 
      51             :     PeerConstPtr peer_;
      52             :     std::string vrf_name_;
      53             :     DISALLOW_COPY_AND_ASSIGN(AgentRouteKey);
      54             : };
      55             : 
      56             : struct AgentRouteData : public AgentData {
      57             :     enum Type {
      58             :         ADD_DEL_CHANGE,
      59             :         ROUTE_PREFERENCE_CHANGE,
      60             :         IPAM_SUBNET,
      61             :     };
      62       11366 :     AgentRouteData(Type type, bool is_multicast, uint64_t sequence_number):
      63       11366 :         type_(type), is_multicast_(is_multicast),
      64       11366 :         sequence_number_(sequence_number) { }
      65       11366 :     virtual ~AgentRouteData() { }
      66             : 
      67             :     virtual std::string ToString() const = 0;
      68             :     virtual AgentPath *CreateAgentPath(const Peer *peer, AgentRoute *rt) const;
      69             :     virtual bool AddChangePathExtended(Agent *agent, AgentPath *path,
      70             :                                        const AgentRoute *rt) = 0;
      71          36 :     virtual bool CanDeletePath(Agent *agent, AgentPath *path,
      72             :                                const AgentRoute *rt) const {
      73          36 :         return true;
      74             :     }
      75        4589 :     virtual bool UpdateRoute(AgentRoute *rt) {return false;}
      76             : 
      77             :     bool AddChangePath(Agent *agent, AgentPath *path, const AgentRoute *rt);
      78        1769 :     bool is_multicast() const {return is_multicast_;}
      79          81 :     uint64_t sequence_number() const {return sequence_number_;}
      80             : 
      81             :     Type type_;
      82             :     bool is_multicast_;
      83             :     uint64_t sequence_number_;
      84             :     DISALLOW_COPY_AND_ASSIGN(AgentRouteData);
      85             : };
      86             : 
      87             : struct RouteComparator {
      88             :     bool operator() (const AgentRoute *rt1, const AgentRoute *rt2) const;
      89             : };
      90             : 
      91             : struct NHComparator {
      92             :     bool operator() (const NextHop *nh1, const NextHop *nh2) const;
      93             : };
      94             : 
      95             : struct RouteTableWalkerState {
      96         444 :     RouteTableWalkerState(LifetimeActor *actor) : rt_delete_ref_(this, actor) {
      97         444 :     }
      98             : 
      99         444 :     ~RouteTableWalkerState() {
     100         444 :         rt_delete_ref_.Reset(NULL);
     101         444 :     }
     102         444 :     void ManagedDelete() { }
     103             : 
     104             :     LifetimeRef<RouteTableWalkerState> rt_delete_ref_;
     105             : };
     106             : 
     107             : /// @brief Agent supports multiple route tables - Inet-unicast (IPv4/IPv6),
     108             : /// Inet-multicast, bridge, EVPN (Type2/Type5). This base class contains
     109             : /// common code for all types of route tables.
     110             : class AgentRouteTable : public RouteTable {
     111             : public:
     112             :     static const int kPartitionCount = 1;
     113             :     typedef std::set<const AgentRoute *, RouteComparator> UnresolvedRouteTree;
     114             :     typedef std::set<const NextHop *, NHComparator> UnresolvedNHTree;
     115             : 
     116             :     AgentRouteTable(DB *db, const std::string &name);
     117             :     virtual ~AgentRouteTable();
     118             : 
     119        4960 :     virtual int PartitionCount() const { return kPartitionCount; }
     120             :     virtual std::unique_ptr<DBEntry> AllocEntry(const DBRequestKey *k) const;
     121       48364 :     virtual size_t Hash(const DBEntry *entry) const {return 0;}
     122       22101 :     virtual size_t Hash(const DBRequestKey *key) const {return 0;}
     123             : 
     124             :     virtual Agent::RouteTableType GetTableType() const = 0;
     125             :     virtual std::string GetTableName() const = 0;
     126             : 
     127         831 :     virtual void ProcessDelete(AgentRoute *rt) { }
     128         831 :     virtual void ProcessAdd(AgentRoute *rt) { }
     129             :     virtual void NotifyEntry(AgentRoute *entry);
     130             : 
     131           0 :     virtual AgentSandeshPtr GetAgentSandesh(const AgentSandeshArguments *args,
     132             :                                             const std::string &context) {
     133           0 :         return AgentSandeshPtr();
     134             :     }
     135       15548 :     virtual SandeshTraceBufferPtr GetOperDBTraceBuf() const {return OperDBTraceBuf;}
     136             : 
     137             :     // Unresolved route tree accessors
     138           0 :     UnresolvedRouteTree::const_iterator unresolved_route_begin() const {
     139           0 :         return unresolved_rt_tree_.begin();
     140             :     }
     141           0 :     UnresolvedRouteTree::const_iterator unresolved_route_end() const {
     142           0 :         return unresolved_rt_tree_.end();
     143             :     }
     144          10 :     int unresolved_route_size() const { return unresolved_rt_tree_.size(); }
     145             : 
     146             :     // Unresolved NH tree accessors
     147             :     void AddUnresolvedNH(const NextHop *);
     148             :     void RemoveUnresolvedNH(const NextHop *);
     149             :     void EvaluateUnresolvedNH(void);
     150           0 :     UnresolvedNHTree::const_iterator unresolved_nh_begin() const {
     151           0 :         return unresolved_nh_tree_.begin();
     152             :     }
     153           0 :     UnresolvedNHTree::const_iterator unresolved_nh_end() const {
     154           0 :         return unresolved_nh_tree_.end();
     155             :     }
     156             :     void EvaluateUnresolvedRoutes(void);
     157             :     void AddUnresolvedRoute(const AgentRoute *rt);
     158             :     void RemoveUnresolvedRoute(const AgentRoute *rt);
     159             : 
     160       93332 :     Agent *agent() const { return agent_; }
     161             :     const std::string &vrf_name() const;
     162        1548 :     uint32_t vrf_id() const {return vrf_id_;}
     163             :     VrfEntry *vrf_entry() const;
     164             :     AgentRoute *FindActiveEntry(const AgentRouteKey *key);
     165             :     AgentRoute *FindActiveEntryNoLock(const AgentRouteKey *key);
     166             :     AgentRoute *FindActiveEntry(const AgentRoute *key);
     167             :     AgentRoute *FindActiveEntryNoLock(const AgentRoute *key);
     168             : 
     169             :     // Set VRF for the route-table
     170             :     void SetVrf(VrfEntry * vrf);
     171             : 
     172             :     // Helper functions to delete routes
     173             :     bool DelExplicitRouteWalkerCb(DBTablePartBase *part, DBEntryBase *entry);
     174             : 
     175             :     // Lifetime actor routines
     176             :     LifetimeActor *deleter();
     177             :     void ManagedDelete();
     178             :     virtual void RetryDelete();
     179             : 
     180             :     // Process DBRequest inline
     181             :     void Process(DBRequest &req);
     182             : 
     183             :     // Path comparator
     184             :     static bool PathSelection(const Path &path1, const Path &path2);
     185             :     static const std::string &GetSuffix(Agent::RouteTableType type);
     186             : 
     187             :     void AddChangeInput(DBTablePartition *part, VrfEntry *vrf, AgentRoute *rt,
     188             :                         AgentRouteKey *key, AgentRouteData *data);
     189             :     AgentRoute *LocateRoute(DBTablePartition *part, VrfEntry *vrf,
     190             :                             AgentRoute *rt, AgentRouteKey *key,
     191             :                             AgentRouteData *data, bool *notify);
     192             : 
     193             : private:
     194             :     class DeleteActor;
     195             :     void DeleteRouteDone(DBTable::DBTableWalkRef walk_ref, DBTableBase *base,
     196             :                          RouteTableWalkerState *state);
     197             : 
     198             :     void Input(DBTablePartition *part, DBClient *client, DBRequest *req);
     199             : 
     200             :     Agent *agent_;
     201             :     uint32_t vrf_id_;
     202             :     VrfEntryRef vrf_entry_;
     203             :     boost::scoped_ptr<DeleteActor> deleter_;
     204             :     LifetimeRef<AgentRouteTable> vrf_delete_ref_;
     205             :     UnresolvedRouteTree unresolved_rt_tree_;
     206             :     UnresolvedNHTree unresolved_nh_tree_;
     207             :     // VRF is stored to identify which VRF this table belonged to
     208             :     // in case lifetimeactor has reset the vrf_.
     209             :     SandeshTraceBufferPtr OperDBTraceBuf;
     210             :     DISALLOW_COPY_AND_ASSIGN(AgentRouteTable);
     211             : };
     212             : 
     213             : #define OPER_TRACE_ROUTE(obj, ...)\
     214             : do {\
     215             :    Oper##obj::TraceMsg(GetOperDBTraceBuf(), __FILE__, __LINE__, __VA_ARGS__);\
     216             : } while (false)
     217             : 
     218             : #define OPER_TRACE_ROUTE_ENTRY(obj, table, ...)\
     219             : do {\
     220             :    Oper##obj::TraceMsg(table->GetOperDBTraceBuf(),\
     221             :                        __FILE__, __LINE__, __VA_ARGS__);\
     222             : } while (false)
     223             : 
     224             : /// @brief Base class for all Route entries in agent
     225             : class AgentRoute : public Route {
     226             : public:
     227             :     enum Trace {
     228             :         ADD,
     229             :         DEL,
     230             :         ADD_PATH,
     231             :         DELETE_PATH,
     232             :         CHANGE_PATH,
     233             :         STALE_PATH,
     234             :     };
     235             : 
     236             :     typedef DependencyList<AgentRoute, AgentRoute> RouteDependencyList;
     237             :     typedef DependencyList<NextHop, AgentRoute> TunnelNhDependencyList;
     238             : 
     239       27099 :     AgentRoute(VrfEntry *vrf, bool is_multicast,
     240       27099 :                const std::string &intf_route_type = "interface") :
     241       27099 :         Route(), vrf_(vrf), is_multicast_(is_multicast),
     242       27099 :         intf_route_type_(intf_route_type), dependent_route_table_(NULL) { }
     243       27099 :     virtual ~AgentRoute() { }
     244             : 
     245             :     // Virtual functions from base DBEntry
     246             :     virtual bool IsLess(const DBEntry &rhs) const;
     247             :     virtual KeyPtr GetDBRequestKey() const = 0;
     248             :     virtual void SetKey(const DBRequestKey *key) = 0;
     249             : 
     250             :     // Virtual functions defined by AgentRoute
     251             :     virtual int CompareTo(const Route &rhs) const = 0;
     252             :     virtual Agent::RouteTableType GetTableType() const = 0;
     253             :     virtual bool DBEntrySandesh(Sandesh *sresp, bool stale) const = 0;
     254             :     virtual std::string ToString() const = 0;
     255             :     virtual const std::string GetAddressString() const = 0;
     256             :     virtual const std::string GetSourceAddressString() const = 0;
     257           0 :     virtual bool ReComputePathDeletion(AgentPath *path) {return false;}
     258        1870 :     virtual bool ReComputePathAdd(AgentPath *path) {return false;}
     259             :     virtual uint32_t GetActiveLabel() const;
     260             :     virtual AgentPath *FindPathUsingKeyData(const AgentRouteKey *key,
     261             :                                             const AgentRouteData *data) const;
     262             :     virtual AgentPath *FindPath(const Peer *peer) const;
     263           0 :     virtual bool RecomputeRoutePath(Agent *agent,
     264             :                              DBTablePartition *part,
     265             :                              AgentPath *path,
     266           0 :                              AgentRouteData *data) {return false;}
     267             :     //Can be used for operations related to updation of route.
     268        7351 :     virtual void UpdateDerivedRoutes(AgentRouteTable *table,
     269             :                                      const AgentPath *path,
     270             :                                      bool active_path_changed) {
     271        7351 :     }
     272             :     //Can be used for operations resulting from deletion of route.
     273        1431 :     virtual void DeleteDerivedRoutes(AgentRouteTable *table) { }
     274             :     // Accessor functions
     275       36293 :     bool is_multicast() const {return is_multicast_;}
     276      100433 :     VrfEntry *vrf() const {return vrf_;}
     277             :     uint32_t vrf_id() const;
     278         810 :     const std::string &intf_route_type() const { return intf_route_type_; }
     279           0 :     void set_intf_route_type(const std::string &intf_route_type) {
     280           0 :         intf_route_type_ = intf_route_type;
     281           0 :     }
     282           0 :     const std::string &origin_vn_name() const {return origin_vn_name_; };
     283        2598 :     void set_origin_vn_name(const VnListType &dest_vn_list) {
     284        2598 :         for (const auto &vn_nm : dest_vn_list) {
     285        2261 :             if (vn_nm == "unresolved") {
     286           0 :                 continue;
     287             :             }
     288             :             else {
     289        2261 :                 origin_vn_name_ = vn_nm;
     290        2261 :                 return;
     291             :             }
     292             :         };
     293         337 :         origin_vn_name_ = Agent::NullString();
     294             :     }
     295             : 
     296             :     AgentPath *FindLocalPath() const;
     297             :     AgentPath *FindLocalVmPortPath() const;
     298             : 
     299             :     /// @brief Finds path to an interface or a composite of interfaces and
     300             :     /// returns it. The priority is given to composite: if both an interface
     301             :     /// and a composite are present, then the composite path is returned
     302             :     /// @return the pointer to AgentPath if a proper path found or NULL
     303             :     const AgentPath *FindIntfOrCompLocalVmPortPath() const; 
     304             :     AgentPath *GetLocalVmPortPath() const;
     305             :     const AgentPath *GetActivePath() const;
     306             :     const NextHop *GetActiveNextHop() const;
     307             :     const std::string &dest_vn_name() const;
     308             :     bool IsRPFInvalid() const;
     309             : 
     310             :     void EnqueueRouteResync() const;
     311             :     void ResyncTunnelNextHop();
     312             :     bool HasUnresolvedPath();
     313             :     bool Sync(void);
     314             : 
     315             :     //TODO Move dependantroutes and nh  to inet4
     316             :     void UpdateDependantRoutes();// analogous to updategatewayroutes
     317           2 :     bool IsDependantRouteEmpty() { return dependant_routes_.empty(); }
     318           2 :     bool IsTunnelNHListEmpty() { return tunnel_nh_list_.empty(); }
     319             : 
     320             :     void FillTrace(RouteInfo &route, Trace event, const AgentPath *path) const;
     321             :     bool WaitForTraffic() const;
     322             : 
     323             :     bool DeleteAllBgpPath(DBTablePartBase *part, AgentRouteTable *table);
     324             :     void DeletePathFromPeer(DBTablePartBase *part, AgentRouteTable *table,
     325             :                             AgentPath *path);
     326             :     bool SubOpResyncInput(VrfEntry *vrf, AgentRouteTable *table,
     327             :                           AgentPath **path_ptr, AgentRouteKey *key,
     328             :                           AgentRouteData *data);
     329             :     bool SubOpAddChangeInput(VrfEntry *vrf, AgentRouteTable *table,
     330             :                              AgentPath **path_ptr, AgentRouteKey *key,
     331             :                              AgentRouteData *data, bool route_added);
     332             :     void DeleteInput(DBTablePartition *part, AgentRouteTable *table,
     333             :                      AgentRouteKey *key, AgentRouteData *data);
     334             :     void AddUnresolvedRouteToTable(AgentRouteTable *table);
     335             :     void RemoveUnresolvedRouteFromTable(AgentRouteTable *table);
     336             :     /// Returns the length of a stored prefix address
     337           0 :     virtual uint8_t prefix_length() const { return 0; }
     338             : protected:
     339           0 :     void SetVrf(VrfEntry *vrf) { vrf_ = vrf; }
     340             :     void RemovePath(AgentPath *path);
     341             :     void InsertPath(const AgentPath *path);
     342             :     virtual void HandleMulticastLabel(const Agent *agent,
     343             :                                             AgentPath *path,
     344             :                                             const AgentPath *local_peer_path,
     345             :                                             const AgentPath *local_vm_peer_path,
     346             :                                             bool del, uint32_t *evpn_label);
     347             :     virtual bool ReComputeMulticastPaths(AgentPath *path, bool del);
     348             :     virtual void HandleDeviceMastershipUpdate(AgentPath *path, bool del);
     349        1254 :     virtual Composite::Type GetMulticastCompType() { return Composite::L2COMP; }
     350             :     const AgentRouteTable *GetDependentRouteTable(void) const {
     351             :         return dependent_route_table_;
     352             :     }
     353           0 :     virtual bool ValidateMcastSrc() const { return true; }
     354             : 
     355             : private:
     356             :     friend class AgentRouteTable;
     357             :     //EcmpData can insert/delete path
     358             :     friend class EcmpData;
     359             : 
     360             :     bool ProcessPath(Agent *agent, DBTablePartition *part, AgentPath *path,
     361             :                      AgentRouteData *data);
     362             : 
     363             :     VrfEntry *vrf_;
     364             :     // Unicast table can contain routes for few multicast address
     365             :     // (ex. subnet multicast). Flag to specify if this is multicast route
     366             :     bool is_multicast_;
     367             :     std::string intf_route_type_;
     368             :     std::string origin_vn_name_;
     369             :     AgentRouteTable *dependent_route_table_;
     370         454 :     DEPENDENCY_LIST(AgentRoute, AgentRoute, dependant_routes_);
     371          96 :     DEPENDENCY_LIST(NextHop, AgentRoute, tunnel_nh_list_);
     372             :     DISALLOW_COPY_AND_ASSIGN(AgentRoute);
     373             : };
     374             : 
     375             : /// @brief This class defines interfaces for manipulating the prefix
     376             : /// of a route stored in an Agent VRF table
     377             : template <class PrefixType>
     378             : class AgentRoutePrefix {
     379             : public:
     380             : 
     381             :     /// @brief Creates a new route prefix
     382       27099 :     AgentRoutePrefix(const PrefixType& new_prefix, uint8_t new_plen)
     383       27099 :     : prefix_address_(new_prefix), prefix_length_(new_plen) {}
     384             : 
     385             :     /// @brief The destructor of a route prefix
     386       27099 :     ~AgentRoutePrefix(){}
     387             : 
     388             :     /// @brief Returns the value of a stored prefix address
     389             :     /// (IPv4, IPv6 or MAC address)
     390      309520 :     virtual const PrefixType& prefix_address() const {return prefix_address_;}
     391             : 
     392             :     /// @brief Sets the length of a stored prefix address
     393          69 :     void set_prefix_length(uint8_t new_plen) {
     394          69 :         prefix_length_ = new_plen;
     395          69 :     }
     396             : 
     397             : protected:
     398             : 
     399             :     /// @brief The prefix address
     400             :     PrefixType prefix_address_;
     401             : 
     402             :     /// @brief The prefix length
     403             :     uint8_t prefix_length_;
     404             : 
     405             : private:
     406             : 
     407             :     /// @brief Forbid default ctor
     408             :     AgentRoutePrefix();
     409             : 
     410             :     DISALLOW_COPY_AND_ASSIGN(AgentRoutePrefix);
     411             : };
     412             : 
     413             : #define GETPEERNAME(peer) (peer)? peer->GetName() : ""
     414             : #define AGENT_ROUTE_LOG(table, msg, route, vrf, peer_info)\
     415             : do {\
     416             :     AgentRouteLog::TraceMsg(table->GetOperDBTraceBuf(), __FILE__, __LINE__,\
     417             :                             msg, route, vrf, peer_info);\
     418             : } while (false)
     419             : 
     420             : #endif

Generated by: LCOV version 1.14