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