LCOV - code coverage report
Current view: top level - vnsw/agent/oper - path_preference.h (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 42 42 100.0 %
Date: 2026-11-09 02:10:49 Functions: 23 23 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             : #ifndef __ROUTE_PREFERENCE_H__
       6             : #define __ROUTE_PREFERENCE_H__
       7             : 
       8             : #include <boost/statechart/custom_reaction.hpp>
       9             : #include <boost/statechart/event.hpp>
      10             : #include <boost/statechart/simple_state.hpp>
      11             : #include <boost/statechart/state.hpp>
      12             : #include <boost/statechart/state_machine.hpp>
      13             : 
      14             : namespace sc = boost::statechart;
      15             : struct Init;
      16             : struct WaitForTraffic;
      17             : struct TrafficSeen;
      18             : struct ActiveActiveState;
      19             : class PathPreferenceModule;
      20             : 
      21             : #define PATH_PREFERENCE_TRACE(...)                                   \
      22             : do {                                                                      \
      23             :    PathPreferenceTrace::TraceMsg(PathPreferenceTraceBuf, __FILE__, __LINE__,\
      24             :                             ##__VA_ARGS__);                               \
      25             : } while (false) \
      26             : 
      27             : //Per Path state machine to determine preference of a path based on
      28             : //traffic(GARP or flow from VM)
      29             : class PathPreferenceSM:
      30             :     public sc::state_machine<PathPreferenceSM, Init> {
      31             :     typedef DependencyList<PathPreferenceSM, PathPreferenceSM> PathDependencyList;
      32             : public:
      33             :     static const uint32_t kMinInterval = 4 * 1000;
      34             :     static const uint32_t kMaxInterval = 32 * 1000;
      35             :     static const uint32_t kMaxFlapCount = 5;
      36             :     PathPreferenceSM(Agent *agent, const Peer *peer,
      37             :                      AgentRoute *rt, bool dependent_rt,
      38             :                      const PathPreference &pref);
      39             :     ~PathPreferenceSM();
      40        3002 :     uint32_t sequence() const {return path_preference_.sequence();}
      41        1335 :     uint32_t preference() const {return path_preference_.preference();}
      42        1182 :     bool wait_for_traffic() const {return path_preference_.wait_for_traffic();}
      43        1820 :     bool ecmp() const {return path_preference_.ecmp();}
      44        1182 :     uint32_t timeout() const { return timeout_;}
      45             : 
      46             :     uint64_t last_stable_high_priority_change_at() const {
      47             :         return last_stable_high_priority_change_at_;
      48             :     }
      49             :     uint32_t flap_count() const { return flap_count_;}
      50             : 
      51        1415 :     bool is_dependent_rt() const { return is_dependent_rt_;}
      52         164 :     void set_sequence(uint32_t seq_no) {
      53         164 :         path_preference_.set_sequence(seq_no);
      54         164 :     }
      55             : 
      56         458 :     void set_preference(uint32_t preference) {
      57         458 :         path_preference_.set_preference(preference);
      58         458 :     }
      59             : 
      60         458 :     void set_wait_for_traffic(bool wait_for_traffic) {
      61         458 :         path_preference_.set_wait_for_traffic(wait_for_traffic);
      62         458 :     }
      63             : 
      64             :     void set_ecmp(bool ecmp) {
      65             :         path_preference_.set_ecmp(ecmp);
      66             :     }
      67             : 
      68        6066 :     void set_seen(bool seen) {
      69        6066 :         seen_ = seen;
      70        6066 :     }
      71             : 
      72         386 :     void set_max_sequence(uint32_t seq) {
      73         386 :         max_sequence_ = seq;
      74         386 :     }
      75             : 
      76             :     void set_timeout(uint32_t timeout) {
      77             :         timeout_ = timeout;
      78             :     }
      79             : 
      80             :     void set_last_stable_high_priority_change_at(uint64_t timestamp) {
      81             :         last_stable_high_priority_change_at_ = timestamp;
      82             :     }
      83             : 
      84        3343 :     void set_dependent_rt(PathPreferenceSM *sm) {
      85        3343 :         dependent_rt_.reset(sm);
      86        3343 :     }
      87             : 
      88        3343 :     void set_is_dependent_rt(bool dependent_path) {
      89        3343 :         is_dependent_rt_ = dependent_path;
      90        3343 :     }
      91             : 
      92        3343 :     void set_dependent_ip(const IpAddress &ip) {
      93        3343 :         path_preference_.set_dependent_ip(ip);
      94        3343 :     }
      95             : 
      96         294 :     IpAddress dependent_ip() {
      97         294 :         return path_preference_.dependent_ip();
      98             :     }
      99             : 
     100             :     bool IsFlap() const;
     101        3447 :     bool seen() { return seen_; }
     102         233 :     uint32_t max_sequence() const { return max_sequence_;}
     103             :     void Process();
     104             :     void Delete();
     105             :     void Log(std::string state);
     106             :     void EnqueuePathChange();
     107             :     bool Retry();
     108             :     void StartRetryTimer();
     109             :     void CancelRetryTimer();
     110             :     bool RetryTimerRunning();
     111             :     void IncreaseRetryTimeout();
     112             :     void DecreaseRetryTimeout();
     113             :     bool IsPathFlapping() const;
     114             :     bool IsPathStable() const;
     115             :     void UpdateFlapTime();
     116             :     void UpdateDependentRoute();
     117             : private:
     118             :     Agent *agent_;
     119             :     const Peer *peer_;
     120             :     AgentRoute *rt_;
     121             :     PathPreference path_preference_;
     122             :     uint32_t max_sequence_;
     123             :     bool seen_;
     124             :     Timer *timer_;
     125             :     uint32_t timeout_;
     126             :     uint64_t last_stable_high_priority_change_at_;
     127             :     uint64_t backoff_timer_fired_time_;
     128             :     uint32_t flap_count_;
     129             :     bool is_dependent_rt_;
     130             :     DependencyRef<PathPreferenceSM, PathPreferenceSM> dependent_rt_;
     131        1184 :     DEPENDENCY_LIST(PathPreferenceSM, PathPreferenceSM, dependent_routes_);
     132             : };
     133             : 
     134             : //Per Route state machine containing a map for all
     135             : //local path state machine data
     136             : class PathPreferenceState: public DBState {
     137             : public:
     138             :     typedef std::map<const Peer *, PathPreferenceSM *> PeerPathPreferenceMap;
     139             :     PathPreferenceState(Agent *agent, AgentRoute *rt_);
     140             :     ~PathPreferenceState();
     141             :     void Process(bool &should_resolve);
     142             :     PathPreferenceSM *GetSM(const Peer *);
     143             :     PathPreferenceSM* GetDependentPath(const AgentPath *path) const;
     144             : private:
     145             :     bool GetRouteListenerId(const VrfEntry *vrf,
     146             :                             const Agent::RouteTableType &table,
     147             :                             DBTableBase::ListenerId &rt_id) const;
     148             :     Agent *agent_;
     149             :     AgentRoute *rt_;
     150             :     PeerPathPreferenceMap path_preference_peer_map_;
     151             : };
     152             : 
     153             : //Per VM interface state, containing floating IP
     154             : //and static route a interface contains
     155             : struct PathPreferenceIntfState : public DBState {
     156             :     PathPreferenceIntfState(const VmInterface *intf);
     157             :     struct RouteAddrList {
     158             :         RouteAddrList();
     159             :         RouteAddrList(const Address::Family &family, const IpAddress &ip,
     160             :                       uint32_t plen, const std::string &vrf);
     161             :         bool operator<(const RouteAddrList &rhs) const;
     162             :         bool operator==(const RouteAddrList &rhs) const;
     163             : 
     164             :         Address::Family family_;
     165             :         IpAddress ip_;
     166             :         uint32_t plen_;
     167             :         std::string vrf_name_;
     168             :         mutable bool seen_;
     169             :     };
     170             :     uint32_t DependentRouteListSize() const { return dependent_rt_.size(); }
     171             : private:
     172             :     const VmInterface *intf_;
     173             :     RouteAddrList instance_ip_;
     174             :     std::set<RouteAddrList> dependent_rt_;
     175             : };
     176             : 
     177             : struct PathPreferenceVrfState: public DBState {
     178          74 :     PathPreferenceVrfState(DBTableBase::ListenerId uc_rt_id,
     179             :                            DBTableBase::ListenerId evpn_rt_id,
     180             :                            DBTableBase::ListenerId uc6_rt_id,
     181          74 :                            DBTableBase::ListenerId mpls_rt_id):
     182          74 :         uc_rt_id_(uc_rt_id), evpn_rt_id_(evpn_rt_id),
     183          74 :         uc6_rt_id_(uc6_rt_id),mpls_rt_id_(mpls_rt_id) {}
     184             :     DBTableBase::ListenerId uc_rt_id_;
     185             :     DBTableBase::ListenerId evpn_rt_id_;
     186             :     DBTableBase::ListenerId uc6_rt_id_;
     187             :     DBTableBase::ListenerId mpls_rt_id_;
     188             : };
     189             : 
     190             : struct PathPreferenceRouteListener : public DBState {
     191             :     PathPreferenceRouteListener(Agent *agent, AgentRouteTable *table);
     192             :     virtual void Delete();
     193             : 
     194             :     void Notify(DBTablePartBase *partition, DBEntryBase *e);
     195             :     void Init();
     196             :     bool DeleteState(DBTablePartBase *partition, DBEntryBase *e);
     197             :     void Walkdone(DBTable::DBTableWalkRef walk_ref, DBTableBase *partition,
     198             :                   PathPreferenceRouteListener *state);
     199         296 :     DBTableBase::ListenerId id() const { return id_;}
     200             :     void ManagedDelete();
     201         296 :     void set_deleted() {deleted_ = true;}
     202             :     bool deleted() const {return deleted_;}
     203             : private:
     204             :     Agent *agent_;
     205             :     AgentRouteTable *rt_table_;
     206             :     DBTableBase::ListenerId id_;
     207             :     LifetimeRef<PathPreferenceRouteListener> table_delete_ref_;
     208             :     bool deleted_;
     209             :     DBTable::DBTableWalkRef managed_delete_walk_ref_;
     210             : };
     211             : 
     212             : class PathPreferenceModule {
     213             : public:
     214             :     struct PathPreferenceEventContainer {
     215             :         IpAddress ip_;
     216             :         uint32_t plen_;
     217             :         MacAddress mac_;
     218             :         uint32_t interface_index_;
     219             :         uint32_t vrf_index_;
     220             :         uint32_t vxlan_id_;
     221             :         boost::intrusive_ptr<const sc::event_base> event;
     222             :     };
     223             : 
     224             :     PathPreferenceModule(Agent *agent);
     225             :     void Init();
     226             :     void Shutdown();
     227             :     void VrfNotify(DBTablePartBase *partition, DBEntryBase *e);
     228             :     void EnqueueTrafficSeen(IpAddress ip, uint32_t plen,
     229             :                             uint32_t interface_index, uint32_t vrf_index,
     230             :                             const MacAddress &mac);
     231             :     bool DequeueEvent(PathPreferenceEventContainer e);
     232             :     Agent *agent() { return agent_;}
     233         616 :     DBTableBase::ListenerId vrf_id() const { return vrf_id_;}
     234             :     DBTableBase::ListenerId intf_id() const { return intf_id_;}
     235             :     void AddUnresolvedPath(PathPreferenceState *sm);
     236             :     void DeleteUnresolvedPath(PathPreferenceState *sm);
     237             :     void Resolve();
     238             : private:
     239             :     Agent *agent_;
     240             :     DBTableBase::ListenerId vrf_id_;
     241             :     DBTableBase::ListenerId intf_id_;
     242             :     WorkQueue<PathPreferenceEventContainer> work_queue_;
     243             :     std::set<PathPreferenceState *> unresolved_paths_;
     244             : };
     245             : #endif

Generated by: LCOV version 1.14