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: 2 76 2.6 %
Date: 2026-06-22 02:21:21 Functions: 2 46 4.3 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.14