LCOV - code coverage report
Current view: top level - vnsw/agent/oper - health_check.h (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 8 79 10.1 %
Date: 2026-11-09 02:10:49 Functions: 4 47 8.5 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2016 Juniper Networks, Inc. All rights reserved.
       3             :  * Copyright Contributors to the OpenSDN project
       4             :  */
       5             : 
       6             : #ifndef SRC_VNSW_AGENT_SERVICES_HEALTH_CHECK_H_
       7             : #define SRC_VNSW_AGENT_SERVICES_HEALTH_CHECK_H_
       8             : 
       9             : #include <boost/scoped_ptr.hpp>
      10             : #include <cmn/agent.h>
      11             : #include <oper_db.h>
      12             : 
      13             : extern SandeshTraceBufferPtr HealthCheckTraceBuf;
      14             : #define HEALTH_CHECK_TRACE(obj, ...)\
      15             : do {\
      16             :     HealthCheck##obj::TraceMsg(HealthCheckTraceBuf, __FILE__, __LINE__,\
      17             :                                __VA_ARGS__);\
      18             : } while (false)
      19             : 
      20             : class Interface;
      21             : class HealthCheckTable;
      22             : class HealthCheckService;
      23             : class MetaDataIp;
      24             : class MetaDataIpAllocator;
      25             : class InstanceTask;
      26             : class InstanceTaskExecvp;
      27             : 
      28             : ///////////////////////////////////////////////////////////////////////////////
      29             : // HealthCheck module provides service to monitor status of given service
      30             : // on an interface and updates the interface state accordingly to propagate
      31             : // information accordingly
      32             : ///////////////////////////////////////////////////////////////////////////////
      33             : 
      34             : struct HealthCheckServiceKey : public AgentOperDBKey {
      35           0 :     HealthCheckServiceKey(const boost::uuids::uuid &id) :
      36           0 :         AgentOperDBKey(), uuid_(id) { }
      37           0 :     HealthCheckServiceKey(const boost::uuids::uuid &id, DBSubOperation sub_op) :
      38           0 :         AgentOperDBKey(sub_op), uuid_(id) { }
      39           0 :     virtual ~HealthCheckServiceKey() { }
      40             : 
      41             :     boost::uuids::uuid uuid_;
      42             : };
      43             : 
      44             : struct HealthCheckServiceData : public AgentOperDBData {
      45           0 :     HealthCheckServiceData(Agent *agent, IpAddress dest_ip,
      46             :                            const std::string &name,
      47             :                            const std::string &monitor_type,
      48             :                            const std::string &stype,
      49             :                            uint8_t ip_proto,
      50             :                            const std::string &http_method,
      51             :                            const std::string &url_path,
      52             :                            uint16_t url_port,
      53             :                            const std::string &expected_codes,
      54             :                            uint32_t delay, uint64_t delay_usecs,
      55             :                            uint32_t timeout, uint64_t timeout_usecs,
      56             :                            uint32_t max_retries,
      57             :                            bool is_all_ip,
      58             :                            std::set<IpAddress> cfg_target_ip_list,
      59           0 :                            IFMapNode *ifmap_node) :
      60           0 :         AgentOperDBData(agent, ifmap_node), dest_ip_(dest_ip), name_(name),
      61           0 :         monitor_type_(monitor_type), service_type_(stype), ip_proto_(ip_proto),
      62           0 :         http_method_(http_method), url_path_(url_path), url_port_(url_port),
      63           0 :         expected_codes_(expected_codes), delay_(delay),
      64           0 :         delay_usecs_(delay_usecs), timeout_(timeout),
      65           0 :         timeout_usecs_(timeout_usecs), max_retries_(max_retries),
      66           0 :         is_all_ip_(is_all_ip),
      67           0 :         new_target_ip_list_(cfg_target_ip_list) {
      68           0 :     }
      69           0 :     virtual ~HealthCheckServiceData() {}
      70             : 
      71             :     IpAddress dest_ip_;
      72             :     std::string name_;
      73             :     std::string monitor_type_;
      74             :     // Service type of HealthCheck segment/end-to-end/link-local
      75             :     std::string service_type_;
      76             :     uint8_t ip_proto_;
      77             :     std::string http_method_;
      78             :     std::string url_path_;
      79             :     uint16_t url_port_;
      80             :     std::string expected_codes_;
      81             :     uint32_t delay_;
      82             :     uint64_t delay_usecs_;
      83             :     uint32_t timeout_;
      84             :     uint64_t timeout_usecs_;
      85             :     uint32_t max_retries_;
      86             :     std::set<boost::uuids::uuid> intf_uuid_list_;
      87             :     std::set<boost::uuids::uuid> vn_uuid_list_;
      88             :     bool is_all_ip_;
      89             :     std::set<IpAddress> new_target_ip_list_;
      90             : };
      91             : 
      92             : struct HealthCheckInstanceEvent {
      93             : public:
      94             :     enum EventType {
      95             :         MESSAGE_READ = 0,
      96             :         TASK_EXIT,
      97             :         SET_SERVICE,
      98             :         STOP_TASK,
      99             :         EVENT_MAXIMUM
     100             :     };
     101             : 
     102             :     HealthCheckInstanceEvent(HealthCheckInstanceBase *inst,
     103             :                              HealthCheckService *service, EventType type,
     104             :                              const std::string &message);
     105             :     virtual ~HealthCheckInstanceEvent();
     106             : 
     107             :     HealthCheckInstanceBase *instance_;
     108             :     HealthCheckService *service_;
     109             :     EventType type_;
     110             :     std::string message_;
     111             :     DISALLOW_COPY_AND_ASSIGN(HealthCheckInstanceEvent);
     112             : };
     113             : 
     114             : class HealthCheckInstanceBase {
     115             : public:
     116             : 
     117             :     HealthCheckInstanceBase(HealthCheckService *service,
     118             :                             MetaDataIpAllocator *allocator,
     119             :                             VmInterface *intf,
     120             :                             bool ignore_status_event);
     121             :     virtual ~HealthCheckInstanceBase();
     122             : 
     123             :     virtual bool CreateInstanceTask() = 0;
     124             : 
     125             :     // return true it instance is scheduled to destroy
     126             :     // when API returns false caller need to assure delete of
     127             :     // Health Check Instance
     128             :     virtual bool DestroyInstanceTask() = 0;
     129             :     virtual bool RunInstanceTask() = 0;
     130             :     virtual bool StopInstanceTask() = 0;
     131           0 :     virtual bool UpdateInstanceTask() { return true; }
     132             : 
     133             :     // OnRead Callback for Task
     134             :     void OnRead(const std::string &data);
     135             :     // OnExit Callback for Task
     136             :     void OnExit(const boost::system::error_code &ec);
     137             :     // Callback to enqueue set service
     138             :     void SetService(HealthCheckService *service);
     139             :     // Callback to enqueue stop task
     140             :     void StopTask(HealthCheckService *service);
     141             : 
     142             :     virtual void ResyncTarget(const HealthCheckService *service) const;
     143             :     void set_service(HealthCheckService *service);
     144             :     std::string to_string();
     145           0 :     bool active() {return active_;}
     146           0 :     virtual bool IsRunning() const { return true; }
     147           0 :     HealthCheckService *service() const { return service_.get(); }
     148           0 :     InterfaceRef interface() const { return intf_; }
     149           0 :     MetaDataIp *ip() const { return ip_.get(); }
     150           0 :     const std::string &last_update_time() const { return last_update_time_; }
     151           0 :     bool IsStatusEventIgnored() const { return ignore_status_event_; }
     152           0 :     void set_source_ip(const IpAddress &ip) { source_ip_ = ip; }
     153           0 :     IpAddress get_source_ip() const { return source_ip_; };
     154             :     IpAddress source_ip() const;
     155             :     IpAddress update_source_ip();
     156             :     void set_destination_ip(const IpAddress &ip);
     157             :     IpAddress destination_ip() const;
     158             :     void EnqueueHealthCheckResync(const HealthCheckService *service,
     159             :                                   const VmInterface *itf) const;
     160             : 
     161             : protected:
     162             :     void EnqueueResync(const HealthCheckService *service, Interface *itf) const;
     163             :     friend class HealthCheckTable;
     164             :     // reference to health check service under
     165             :     // which this instance is running
     166             :     HealthCheckServiceRef service_;
     167             :     // Interface associated to this HealthCheck Instance
     168             :     InterfaceRef intf_;
     169             :     // MetaData IP Created for this HealthCheck Instance
     170             :     boost::scoped_ptr<MetaDataIp> ip_;
     171             :     // current status of HealthCheckInstance
     172             :     bool active_;
     173             :     // last update time
     174             :     std::string last_update_time_;
     175             :     // instance is delete marked
     176             :     bool deleted_;
     177             :     // true if the health check up or down status event has to be ignored
     178             :     bool ignore_status_event_;
     179             : 
     180             :     // source IP to be used while doing the health check
     181             :     IpAddress source_ip_;
     182             :     // destination IP for the health check
     183             :     IpAddress destination_ip_;
     184             : 
     185             : private:
     186             :     DISALLOW_COPY_AND_ASSIGN(HealthCheckInstanceBase);
     187             : };
     188             : 
     189             : // Health check instance using the instance task infrastructure
     190             : class HealthCheckInstanceTask : public HealthCheckInstanceBase {
     191             : public:
     192             :     typedef InstanceTaskExecvp HeathCheckProcessInstance;
     193             :     static const std::string kHealthCheckCmd;
     194             : 
     195             :     HealthCheckInstanceTask(HealthCheckService *service,
     196             :                             MetaDataIpAllocator *allocator, VmInterface *intf,
     197             :                             bool ignore_status_event);
     198             :     virtual ~HealthCheckInstanceTask();
     199             : 
     200             :     virtual bool CreateInstanceTask();
     201             :     virtual bool DestroyInstanceTask();
     202             :     virtual bool RunInstanceTask();
     203             :     virtual bool StopInstanceTask();
     204             :     virtual bool IsRunning() const;
     205             : 
     206             : private:
     207             :     friend class HealthCheckTable;
     208             : 
     209             :     void UpdateInstanceTaskCommand();
     210             : 
     211             :     // task managing external running script for status
     212             :     boost::scoped_ptr<HeathCheckProcessInstance> task_;
     213             : 
     214             :     DISALLOW_COPY_AND_ASSIGN(HealthCheckInstanceTask);
     215             : };
     216             : 
     217             : // Health check instance using the services infrastructure
     218             : class HealthCheckInstanceService : public HealthCheckInstanceBase {
     219             : public:
     220             :     HealthCheckInstanceService(HealthCheckService *service,
     221             :                                MetaDataIpAllocator *allocator,
     222             :                                VmInterface *intf, VmInterface *other_intf,
     223             :                                bool ignore_status_event, bool multi_hop);
     224             :     virtual ~HealthCheckInstanceService();
     225             : 
     226             :     virtual bool CreateInstanceTask();
     227             :     virtual bool DestroyInstanceTask();
     228             :     virtual bool RunInstanceTask();
     229             :     virtual bool StopInstanceTask();
     230             :     virtual bool UpdateInstanceTask();
     231             :     virtual void ResyncTarget(const HealthCheckService *service) const;
     232             :     void EnqueueMacIpLearningHCStatus(const HealthCheckService *service) const;
     233             : 
     234             :     typedef boost::function<void()> BfdDownCallback;
     235           0 :     void SetBfdDownCallback(const BfdDownCallback &callback) {
     236           0 :         bfd_down_callback_ = callback;
     237           0 :     }
     238             :     void BfdStateChange(bool up);
     239             : 
     240           0 :     bool is_multi_hop() const { return multi_hop_; }
     241             : 
     242             : private:
     243             :     friend class HealthCheckTable;
     244             : 
     245             :     // Other Interface associated to this HealthCheck Instance when
     246             :     // HealthCheck service type is "segment"
     247             :     InterfaceRef other_intf_;
     248             : 
     249             :     // BFD health check can be single hop or multi hop, when started for a
     250             :     // BGP flow, make it multi hop
     251             :     bool multi_hop_;
     252             : 
     253             :     // True only after BFD has reached Up at least once. This prevents the
     254             :     // initial Down notification from deleting a newly-created BGP flow.
     255             :     bool bfd_up_;
     256             :     BfdDownCallback bfd_down_callback_;
     257             : 
     258             :     DISALLOW_COPY_AND_ASSIGN(HealthCheckInstanceService);
     259             : };
     260             : 
     261             : class HealthCheckMacIpInstanceService : public HealthCheckInstanceService {
     262             : public:
     263             :     HealthCheckMacIpInstanceService(HealthCheckService *service,
     264             :                                MetaDataIpAllocator *allocator,
     265             :                                VmInterface *intf, VmInterface *other_intf,
     266             :                                bool ignore_status_event, bool multi_hop);
     267             :     virtual ~HealthCheckMacIpInstanceService();
     268             : 
     269             :     virtual void ResyncTarget(const HealthCheckService *service) const;
     270           0 :     virtual void set_destination_mac(const MacAddress &mac) {
     271           0 :         mac_ = mac;
     272           0 :     }
     273           0 :     virtual const MacAddress destination_mac() const { return mac_; }
     274             : 
     275             : private:
     276             :     friend class HealthCheckTable;
     277             : 
     278             :     MacAddress mac_;
     279             : 
     280             :     DISALLOW_COPY_AND_ASSIGN(HealthCheckMacIpInstanceService);
     281             : };
     282             : 
     283             : class HealthCheckService : AgentRefCount<HealthCheckService>,
     284             :                            public AgentOperDBEntry {
     285             : public:
     286             :     enum HealthCheckType {
     287             :         PING,
     288             :         HTTP,
     289             :         BFD,
     290             :         SEGMENT,
     291             :         MAX_HEALTH_CHECK_SERVICES
     292             :     };
     293             :     typedef std::map<boost::uuids::uuid, HealthCheckInstanceBase *> InstanceList;
     294             :     typedef std::map<IpAddress, HealthCheckInstanceBase *> IpInstanceList;
     295             : 
     296             :     HealthCheckService(const HealthCheckTable *table,
     297             :                        const boost::uuids::uuid &id);
     298             :     ~HealthCheckService();
     299             : 
     300             :     virtual bool IsLess(const DBEntry &rhs) const;
     301             :     virtual std::string ToString() const;
     302             :     virtual KeyPtr GetDBRequestKey() const;
     303             :     virtual void SetKey(const DBRequestKey *key);
     304           0 :     uint32_t GetRefCount() const {
     305           0 :         return AgentRefCount<HealthCheckService>::GetRefCount();
     306             :     }
     307             : 
     308             :     bool DBEntrySandesh(Sandesh *resp, std::string &name) const;
     309             : 
     310             :     void PostAdd();
     311             :     bool Copy(HealthCheckTable *table, const HealthCheckServiceData *data);
     312             : 
     313             :     HealthCheckInstanceBase *StartHealthCheckService(VmInterface *intrface,
     314             :                                                      VmInterface *paired_vmi,
     315             :                                                      const IpAddress &source_ip,
     316             :                                                      const IpAddress &destination_ip,
     317             :                                                      const MacAddress &destination_mac,
     318             :                                                      bool ignore_status_event,
     319             :                                                      bool multi_hop);
     320           0 :     HealthCheckInstanceBase *StartHealthCheckService(
     321             :                              VmInterface *intrface, const IpAddress &source_ip,
     322             :                              const IpAddress &destination_ip,
     323             :                              const MacAddress destination_mac = MacAddress()) {
     324             :         // health check status event is ignored
     325           0 :         return StartHealthCheckService(intrface, NULL, source_ip,
     326             :                                        destination_ip, destination_mac,
     327           0 :                                        true, true);
     328             :     }
     329             :     void StopHealthCheckService(HealthCheckInstanceBase *instance);
     330             : 
     331             :     void UpdateInstanceServiceReference();
     332             :     void ResyncHealthCheckInterface(const HealthCheckService *service,
     333             :                                     const VmInterface *intf);
     334             :     void UpdateInterfaceInstanceServiceReference(const VmInterface *intf);
     335             :     void DeleteInstances();
     336             : 
     337           0 :     const boost::uuids::uuid &uuid() const { return uuid_; }
     338           0 :     const std::string &name() const { return name_; }
     339             : 
     340             :     uint8_t ip_proto() const { return ip_proto_; }
     341           2 :     uint16_t url_port() const { return url_port_; }
     342           0 :     uint32_t delay() const { return delay_; }
     343           0 :     uint64_t delay_usecs() const { return delay_usecs_; }
     344           0 :     uint32_t timeout() const { return timeout_; }
     345           0 :     uint64_t timeout_usecs() const { return timeout_usecs_; }
     346           0 :     uint32_t max_retries() const { return max_retries_; }
     347           0 :     const std::string &url_path() const { return url_path_; }
     348           0 :     const std::string &monitor_type() const { return monitor_type_; }
     349           0 :     const HealthCheckTable *table() const { return table_; }
     350             :     bool IsInstanceTaskBased() const;
     351             :     bool IsSegmentHealthCheckService() const;
     352             :     bool IsVnIpListHealthCheckService() const;
     353           0 :     HealthCheckType health_check_type() const {
     354           0 :         return health_check_type_;
     355             :     }
     356           0 :     const std::set<boost::uuids::uuid> &GetVnUuidList() {
     357           0 :         return vn_uuid_list_;
     358             :     }
     359           0 :     const std::set<IpAddress> &GetTargetIpList() {
     360           0 :         return target_ip_list_;
     361             :     }
     362           0 :     bool IsTargetIpPresent(IpAddress &ip) {
     363             :  
     364           0 :         if (is_hc_enable_all_ip_ ||
     365           0 :                 target_ip_list_.find(ip) != target_ip_list_.end()) {
     366           0 :             return true;
     367             :         }
     368           0 :         return false;
     369             :     }
     370           1 :     IpAddress dest_ip() const { return dest_ip_;}
     371           0 :     bool IsHcEnableAllTargetIp() const {return is_hc_enable_all_ip_;}
     372             : 
     373             : private:
     374             :     friend struct HealthCheckInstanceEvent;
     375             : 
     376             :     HealthCheckType GetHealthCheckType() const;
     377             : 
     378             :     const HealthCheckTable *table_;
     379             :     boost::uuids::uuid uuid_;
     380             :     IpAddress dest_ip_;
     381             :     std::string name_;
     382             :     // monitor type of service PING/HTTP/BFD etc
     383             :     std::string monitor_type_;
     384             :     // Service type of HealthCheck segment/end-to-end/link-local
     385             :     std::string service_type_;
     386             :     // ip_proto derived from monitor_type_
     387             :     uint8_t ip_proto_;
     388             :     std::string http_method_;
     389             :     std::string url_path_;
     390             :     // tcp/udp port numbers derived from url
     391             :     uint16_t url_port_;
     392             :     std::string expected_codes_;
     393             :     uint32_t delay_;
     394             :     uint64_t delay_usecs_;
     395             :     uint32_t timeout_;
     396             :     uint64_t timeout_usecs_;
     397             :     uint32_t max_retries_;
     398             :     // List of interfaces associated to this HealthCheck Service
     399             :     InstanceList intf_list_;
     400             :     HealthCheckType health_check_type_;
     401             : 
     402             :     std::set<boost::uuids::uuid> vn_uuid_list_;
     403             :     std::set<IpAddress> target_ip_list_;
     404             :     bool is_hc_enable_all_ip_;
     405             : 
     406             :     DISALLOW_COPY_AND_ASSIGN(HealthCheckService);
     407             : };
     408             : 
     409             : class HealthCheckTable : public AgentOperDBTable {
     410             : public:
     411             :     enum HealthCheckServiceAction {
     412             :         CREATE_SERVICE,
     413             :         DELETE_SERVICE,
     414             :         RUN_SERVICE,
     415             :         STOP_SERVICE,
     416             :         UPDATE_SERVICE
     417             :     };
     418             :     typedef boost::function<bool(HealthCheckServiceAction,
     419             :                                  HealthCheckInstanceService *)>
     420             :             HealthCheckServiceCallback;
     421             : 
     422             :     typedef boost::function<void(const HealthCheckInstanceService *)>
     423             :             HealthCheckNotifyCallback;
     424             : 
     425             :     HealthCheckTable(Agent *agent, DB *db, const std::string &name);
     426             :     virtual ~HealthCheckTable();
     427             : 
     428             :     static DBTableBase *CreateTable(Agent *agent, DB *db,
     429             :                                     const std::string &name);
     430             : 
     431             :     virtual std::unique_ptr<DBEntry> AllocEntry(const DBRequestKey *k) const;
     432           0 :     virtual size_t Hash(const DBEntry *entry) const {return 0;}
     433           0 :     virtual size_t Hash(const DBRequestKey *key) const {return 0;}
     434             : 
     435             :     virtual DBEntry *OperDBAdd(const DBRequest *req);
     436             :     virtual bool OperDBOnChange(DBEntry *entry, const DBRequest *req);
     437             :     virtual bool OperDBResync(DBEntry *entry, const DBRequest *req);
     438             :     virtual bool OperDBDelete(DBEntry *entry, const DBRequest *req);
     439             : 
     440             :     virtual bool IFNodeToReq(IFMapNode *node, DBRequest &req,
     441             :             const boost::uuids::uuid &u);
     442             :     bool ProcessConfig(IFMapNode *node, DBRequest &req,
     443             :             const boost::uuids::uuid &u);
     444             :     virtual bool IFNodeToUuid(IFMapNode *node, boost::uuids::uuid &u);
     445             :     virtual AgentSandeshPtr GetAgentSandesh(const AgentSandeshArguments *args,
     446             :             const std::string &context);
     447             : 
     448             :     HealthCheckService *Find(const boost::uuids::uuid &u);
     449             : 
     450             :     void InstanceEventEnqueue(HealthCheckInstanceEvent *event) const;
     451             :     bool InstanceEventProcess(HealthCheckInstanceEvent *event);
     452             : 
     453           4 :     void RegisterHealthCheckCallback(HealthCheckServiceCallback fn,
     454             :                                      HealthCheckService::HealthCheckType type) {
     455           4 :         health_check_service_cb_[type] = fn;
     456           4 :     }
     457           0 :     HealthCheckServiceCallback health_check_service_callback(
     458             :                                HealthCheckService::HealthCheckType type) const {
     459           0 :         return health_check_service_cb_[type];
     460             :     }
     461           2 :     void RegisterHealthCheckNotifyCallback(HealthCheckNotifyCallback fn) {
     462           2 :         health_check_notify_cb_ = fn;
     463           2 :     }
     464           0 :     HealthCheckNotifyCallback health_check_notify_callback() const {
     465           0 :         return health_check_notify_cb_;
     466             :     }
     467             : 
     468             : private:
     469             : 
     470             :     WorkQueue<HealthCheckInstanceEvent *> *inst_event_queue_;
     471             :     HealthCheckServiceCallback health_check_service_cb_[HealthCheckService::MAX_HEALTH_CHECK_SERVICES];
     472             :     HealthCheckNotifyCallback health_check_notify_cb_;
     473             :     DISALLOW_COPY_AND_ASSIGN(HealthCheckTable);
     474             : };
     475             : 
     476             : struct HealthCheckResyncInterfaceData : public AgentOperDBData {
     477           0 :        HealthCheckResyncInterfaceData(const Agent *agent, IFMapNode *node,
     478           0 :                                       const VmInterface *intf):
     479           0 :         AgentOperDBData(agent, node), intf_(intf) {}
     480             :     const VmInterface *intf_;
     481             : };
     482             : 
     483             : #endif  // SRC_VNSW_AGENT_SERVICES_HEALTH_CHECK_H_

Generated by: LCOV version 1.14