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

Generated by: LCOV version 1.14