Line data Source code
1 : /* 2 : * Copyright (c) 2015 Juniper Networks, Inc. All rights reserved. 3 : * Copyright Contributors to the OpenSDN project 4 : */ 5 : 6 : #ifndef vnsw_agent_flow_stats_maanger_h 7 : #define vnsw_agent_flow_stats_maanger_h 8 : 9 : #include <atomic> 10 : 11 : 12 : #include <cmn/agent_cmn.h> 13 : #include <cmn/index_vector.h> 14 : #include <uve/stats_collector.h> 15 : #include <uve/interface_uve_stats_table.h> 16 : #include <pkt/flow_table.h> 17 : #include <vrouter/ksync/flowtable_ksync.h> 18 : #include <sandesh/common/flow_types.h> 19 : 20 : extern SandeshTraceBufferPtr FlowExportStatsTraceBuf; 21 : 22 : #define FLOW_EXPORT_STATS_TRACE(...)\ 23 : do {\ 24 : FlowExportStatsTrace::TraceMsg(FlowExportStatsTraceBuf, __FILE__, __LINE__, __VA_ARGS__);\ 25 : } while (false) 26 : 27 : class FlowStatsCollector; 28 : class FlowStatsCollectorObject; 29 : class SessionStatsCollector; 30 : class SessionStatsCollectorObject; 31 : 32 : struct FlowAgingTableKey { 33 146 : FlowAgingTableKey(const uint8_t &protocol, const uint16_t &dst_port): 34 146 : proto(protocol), port(dst_port) {} 35 : 36 : bool operator==(const FlowAgingTableKey &rhs) const { 37 : return (proto == rhs.proto && port == rhs.port); 38 : } 39 : 40 146 : bool operator<(const FlowAgingTableKey &rhs) const { 41 146 : if (proto != rhs.proto) { 42 142 : return proto < rhs.proto; 43 : } 44 : 45 4 : return port < rhs.port; 46 : } 47 : 48 : uint8_t proto; 49 : uint16_t port; 50 : }; 51 : 52 : struct FlowStatsCollectorReq { 53 : enum Event { 54 : INVALID, 55 : ADD_FLOW_STATS_COLLECTOR, 56 : DELETE_FLOW_STATS_COLLECTOR, 57 : FREE_FLOW_STATS_COLLECTOR, 58 : }; 59 : 60 4 : FlowStatsCollectorReq(Event ev, const FlowAgingTableKey &k, 61 4 : uint64_t interval, uint64_t timeout) : 62 4 : event(ev), key(k), flow_stats_interval(interval), 63 4 : flow_cache_timeout(timeout) {} 64 : 65 0 : FlowStatsCollectorReq(Event ev, const FlowAgingTableKey &k): 66 0 : event(ev), key(k) {} 67 : 68 : Event event; 69 : FlowAgingTableKey key; 70 : uint64_t flow_stats_interval; 71 : uint64_t flow_cache_timeout; 72 : }; 73 : 74 : class FlowStatsManager { 75 : public: 76 : static const uint8_t kCatchAllProto = 0x0; 77 : static const uint64_t FlowThresoldUpdateTime = 1000 * 2; 78 : static const uint32_t kDefaultFlowSamplingThreshold = 500; 79 : static const uint32_t kMinFlowSamplingThreshold = 20; 80 : 81 : typedef boost::shared_ptr<FlowStatsCollectorObject> FlowAgingTablePtr; 82 : typedef boost::shared_ptr<SessionStatsCollectorObject> SessionStatsCollectorPtr; 83 : 84 : typedef std::map<const FlowAgingTableKey, FlowAgingTablePtr> 85 : FlowAgingTableMap; 86 : typedef std::pair<const FlowAgingTableKey, FlowAgingTablePtr> 87 : FlowAgingTableEntry; 88 : 89 : FlowStatsManager(Agent *agent); 90 : ~FlowStatsManager(); 91 : 92 2 : Agent* agent() { return agent_; } 93 66 : FlowStatsCollectorObject* default_flow_stats_collector_obj() { 94 66 : return default_flow_stats_collector_obj_.get(); 95 : } 96 4 : SessionStatsCollectorObject* session_stats_collector_obj() { 97 4 : return session_stats_collector_obj_.get(); 98 : } 99 : 100 : //Add protocol + port based flow aging table 101 : void Add(const FlowAgingTableKey &key, 102 : uint64_t flow_stats_interval, 103 : uint64_t flow_cache_timeout); 104 : void Delete(const FlowAgingTableKey &key); 105 : void Free(const FlowAgingTableKey &key); 106 : 107 : //Add flow entry to particular aging table 108 : void AddEvent(FlowEntryPtr &flow); 109 : void DeleteEvent(const FlowEntryPtr &flow, const RevFlowDepParams ¶ms); 110 : void UpdateStatsEvent(const FlowEntryPtr &flow, uint32_t bytes, 111 : uint32_t packets, uint32_t oflow_bytes, 112 : const boost::uuids::uuid &u); 113 : 114 : void Init(uint64_t flow_stats_interval, uint64_t flow_cache_timeout); 115 : void InitDone(); 116 : void Shutdown(); 117 : 118 0 : FlowAgingTableMap::iterator begin() { 119 0 : return flow_aging_table_map_.begin(); 120 : } 121 : 122 0 : FlowAgingTableMap::iterator end() { 123 0 : return flow_aging_table_map_.end(); 124 : } 125 : 126 : FlowStatsCollector* GetFlowStatsCollector(const FlowEntry *p) const; 127 : const FlowStatsCollectorObject* Find(uint32_t proto, uint32_t port) const; 128 : 129 : bool RequestHandler(boost::shared_ptr<FlowStatsCollectorReq> req); 130 : void AddReqHandler(boost::shared_ptr<FlowStatsCollectorReq> req); 131 : void DeleteReqHandler(boost::shared_ptr<FlowStatsCollectorReq> req); 132 : void FreeReqHandler(boost::shared_ptr<FlowStatsCollectorReq> req); 133 : 134 6 : FlowStatsCollectorObject* proto(int protocol) { 135 6 : return protocol_list_[protocol]; 136 : } 137 0 : uint32_t session_export_rate() const { 138 0 : return session_export_rate_; 139 : } 140 : 141 : uint32_t session_export_count() const { 142 : return session_export_count_; 143 : } 144 : 145 : void set_session_export_count(uint32_t count) { 146 : session_export_count_ = count; 147 : } 148 : 149 0 : uint32_t session_export_count_reset() { 150 0 : return session_export_count_.exchange(0); 151 : } 152 : 153 0 : uint32_t session_export_without_sampling_reset() { 154 0 : return session_export_without_sampling_.exchange(0); 155 : } 156 : 157 0 : uint32_t session_export_drops() const { return session_export_drops_; } 158 : 159 0 : uint64_t session_sample_exports() const { return session_sample_exports_; } 160 0 : uint64_t session_msg_exports() const { return session_msg_exports_; } 161 0 : uint64_t session_exports() const { return session_exports_; } 162 : 163 0 : uint64_t session_export_disable_drops() const { 164 0 : return session_export_disable_drops_; 165 : } 166 0 : uint32_t session_export_sampling_drops() const { 167 0 : return session_export_sampling_drops_; 168 : } 169 0 : uint64_t session_global_slo_logging_drops() const { 170 0 : return session_global_slo_logging_drops_; 171 : } 172 0 : uint64_t session_slo_logging_drops() const { 173 0 : return session_slo_logging_drops_; 174 : } 175 0 : void set_sessions_sampled_atleast_once() { 176 0 : sessions_sampled_atleast_once_ = true; 177 0 : } 178 : 179 0 : uint64_t threshold() const { return threshold_;} 180 0 : bool delete_short_flow() const { 181 0 : return delete_short_flow_; 182 : } 183 : 184 163 : void set_delete_short_flow(bool val) { 185 163 : delete_short_flow_ = val; 186 163 : } 187 : static void FlowStatsReqHandler(Agent *agent, uint32_t proto, 188 : uint32_t port, 189 : uint64_t protocol); 190 : void FreeIndex(uint32_t idx); 191 : uint32_t AllocateIndex(); 192 : void UpdateSessionSampleExportStats(uint32_t count); 193 : void UpdateSessionMsgExportStats(uint32_t count); 194 : void UpdateSessionExportStats(uint32_t count, bool first_export, 195 : bool sampled); 196 : 197 : void SetProfileData(ProfileData *data); 198 : void RegisterDBClients(); 199 : friend class AgentUtXmlFlowThreshold; 200 : friend class AgentUtXmlFlowThresholdValidate; 201 : private: 202 : friend struct FlowStatsCollectorReq; 203 : friend class FlowStatsRecordsReq; 204 : friend class FlowStatsCollector; 205 : friend class SessionStatsCollector; 206 : bool UpdateSessionThreshold(void); 207 : void UpdateThreshold(uint64_t new_value, bool check_oflow); 208 : FlowStatsCollectorObject* GetFlowStatsCollectorObject(const FlowEntry *flow) 209 : const; 210 : Agent *agent_; 211 : WorkQueue<boost::shared_ptr<FlowStatsCollectorReq> > request_queue_; 212 : FlowAgingTableMap flow_aging_table_map_; 213 : FlowAgingTablePtr default_flow_stats_collector_obj_; 214 : SessionStatsCollectorPtr session_stats_collector_obj_; 215 : uint64_t prev_flow_export_rate_compute_time_; 216 : uint64_t threshold_; 217 : uint32_t prev_cfg_flow_export_rate_; 218 : uint32_t session_export_rate_; 219 : std::atomic<uint32_t> session_export_count_; 220 : std::atomic<uint64_t> session_sample_exports_; 221 : std::atomic<uint64_t> session_msg_exports_; 222 : std::atomic<uint64_t> session_exports_; 223 : std::atomic<uint64_t> session_export_disable_drops_; 224 : std::atomic<uint64_t> session_export_sampling_drops_; 225 : std::atomic<uint32_t> session_export_without_sampling_; 226 : std::atomic<uint64_t> session_export_drops_; 227 : std::atomic<bool> sessions_sampled_atleast_once_; 228 : std::atomic<uint64_t> session_global_slo_logging_drops_; 229 : std::atomic<uint64_t> session_slo_logging_drops_; 230 : Timer* timer_; 231 : bool delete_short_flow_; 232 : //Protocol based array for minimal tree comparision 233 : FlowStatsCollectorObject* protocol_list_[256]; 234 : IndexVector<FlowStatsCollector *> instance_table_; 235 : }; 236 : #endif //vnsw_agent_flow_stats_manager_h