Line data Source code
1 : /*
2 : * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3 : * Copyright Contributors to the OpenSDN project
4 : */
5 :
6 : #ifndef vnsw_agent_session_stats_collector_h
7 : #define vnsw_agent_session_stats_collector_h
8 :
9 : #include <vrouter/flow_stats/flow_stats_manager.h>
10 : // Forward declaration
11 : class FlowStatsManager;
12 : class SessionStatsReq;
13 : class FlowToSessionMap;
14 : struct SessionSloRuleEntry;
15 : class SessionSloState;
16 :
17 : extern SandeshTraceBufferPtr SessionStatsTraceBuf;
18 :
19 : #define SESSION_STATS_TRACE(obj, ...)\
20 : do {\
21 : SessionStats##obj::TraceMsg(SessionStatsTraceBuf, __FILE__, __LINE__, __VA_ARGS__);\
22 : } while (false)
23 :
24 : struct SessionEndpointKey {
25 : public:
26 : std::string vmi_cfg_name;
27 : std::string local_vn;
28 : std::string remote_vn;
29 : TagList local_tagset;
30 : TagList remote_tagset;
31 : std::string remote_prefix;
32 : std::string match_policy;
33 : bool is_client_session;
34 : bool is_si;
35 400 : SessionEndpointKey() { Reset(); }
36 :
37 : void Reset();
38 : bool IsLess(const SessionEndpointKey &rhs) const;
39 : bool IsEqual(const SessionEndpointKey &rhs) const;
40 : };
41 :
42 : struct SessionAggKey {
43 : public:
44 : IpAddress local_ip;
45 : uint16_t server_port;
46 : uint16_t proto;
47 400 : SessionAggKey() { Reset(); }
48 : void Reset();
49 : bool IsLess(const SessionAggKey &rhs) const;
50 : bool IsEqual(const SessionAggKey &rhs) const;
51 : };
52 :
53 : struct SessionKey {
54 : public:
55 : IpAddress remote_ip;
56 : uint16_t client_port;
57 : boost::uuids::uuid uuid;
58 400 : SessionKey() { Reset(); }
59 :
60 : void Reset();
61 : bool IsLess(const SessionKey &rhs) const;
62 : bool IsEqual(const SessionKey &rhs) const;
63 : };
64 :
65 : struct SessionKeyCmp {
66 565 : bool operator()(const SessionKey &lhs, const SessionKey &rhs) const {
67 565 : return lhs.IsLess(rhs);
68 : }
69 : };
70 :
71 : struct SessionFlowStatsInfo {
72 : public:
73 : FlowEntryPtr flow;
74 : uint8_t gen_id;
75 : uint32_t flow_handle;
76 : boost::uuids::uuid uuid;
77 : uint64_t total_bytes;
78 : uint64_t total_packets;
79 : };
80 :
81 : struct SessionFlowExportInfo {
82 : std::string sg_rule_uuid;
83 : std::string nw_ace_uuid;
84 : std::string aps_rule_uuid;
85 : std::string action;
86 : std::string drop_reason;
87 460 : SessionFlowExportInfo() : sg_rule_uuid(""), nw_ace_uuid(""),
88 460 : aps_rule_uuid(""), action(""), drop_reason("") {
89 460 : }
90 : };
91 :
92 : struct SessionExportInfo {
93 : bool valid;
94 : std::string vm_cfg_name;
95 : std::string other_vrouter;
96 : uint16_t underlay_proto;
97 : UuidList vmi_slo_list;
98 : UuidList vn_slo_list;
99 : SessionFlowExportInfo fwd_flow;
100 : SessionFlowExportInfo rev_flow;
101 230 : SessionExportInfo() : valid(false), vm_cfg_name(""), other_vrouter(""),
102 230 : underlay_proto(0) {}
103 : };
104 :
105 : struct SessionFlowStatsParams {
106 : uint64_t diff_bytes;
107 : uint64_t diff_packets;
108 : uint16_t underlay_src_port;
109 : uint16_t tcp_flags;
110 : bool valid;
111 1034 : SessionFlowStatsParams() : diff_bytes(0), diff_packets(0),
112 1034 : underlay_src_port(0), tcp_flags(0), valid(false) {
113 1034 : }
114 : };
115 :
116 : struct SessionStatsParams {
117 : bool sampled;
118 : SessionFlowStatsParams fwd_flow;
119 : SessionFlowStatsParams rev_flow;
120 517 : SessionStatsParams() : sampled(false), fwd_flow(), rev_flow() {}
121 : };
122 :
123 : struct SessionStatsInfo {
124 : public:
125 : uint64_t setup_time;
126 : uint64_t teardown_time;
127 : bool exported_atleast_once;
128 : bool deleted;
129 : SessionStatsParams del_stats;
130 : bool evicted;
131 : SessionStatsParams evict_stats;
132 : SessionExportInfo export_info;
133 : SessionFlowStatsInfo fwd_flow;
134 : SessionFlowStatsInfo rev_flow;
135 230 : SessionStatsInfo() : setup_time(0), teardown_time(0),
136 230 : exported_atleast_once(false), deleted(false), del_stats(),
137 230 : evicted(false), evict_stats(), export_info(), fwd_flow(), rev_flow() {}
138 : };
139 :
140 : struct SessionPreAggInfo {
141 : public:
142 : typedef std::map<const SessionKey, SessionStatsInfo,
143 : SessionKeyCmp> SessionMap;
144 : SessionMap session_map_;
145 : };
146 :
147 : struct SessionAggKeyCmp {
148 1198 : bool operator()(const SessionAggKey &lhs, const SessionAggKey &rhs) const {
149 1198 : return lhs.IsLess(rhs);
150 : }
151 : };
152 :
153 : struct SessionEndpointInfo {
154 : public:
155 : typedef std::map<const SessionAggKey, SessionPreAggInfo,
156 : SessionAggKeyCmp> SessionAggMap;
157 : SessionAggMap session_agg_map_;
158 : };
159 :
160 : struct SessionEndpointKeyCmp {
161 1278 : bool operator() (const SessionEndpointKey &lhs,
162 : const SessionEndpointKey &rhs) const {
163 1278 : return lhs.IsLess(rhs);
164 : }
165 : };
166 :
167 : class SessionStatsCollector : public StatsCollector {
168 : public:
169 : typedef std::map<const SessionEndpointKey, SessionEndpointInfo,
170 : SessionEndpointKeyCmp> SessionEndpointMap;
171 : typedef WorkQueue<boost::shared_ptr<SessionStatsReq> > Queue;
172 : typedef std::map<FlowEntryPtr, FlowToSessionMap> FlowSessionMap;
173 : typedef std::map<std::string, SessionSloRuleEntry> SessionSloRuleMap;
174 :
175 : static const uint32_t kSessionStatsTimerInterval = 1000;
176 : static const uint32_t kSessionsPerTask = 256;
177 :
178 : uint32_t RunSessionEndpointStats(uint32_t max_count);
179 :
180 : class SessionTask : public Task {
181 : public:
182 : SessionTask(SessionStatsCollector *ssc);
183 : virtual ~SessionTask();
184 : std::string Description() const;
185 : bool Run();
186 : private:
187 : SessionStatsCollector *ssc_;
188 : };
189 :
190 :
191 : SessionStatsCollector(boost::asio::io_context &io, AgentUveBase *uve,
192 : uint32_t instance_id, FlowStatsManager *fsm,
193 : SessionStatsCollectorObject *obj);
194 : virtual ~SessionStatsCollector();
195 : bool Run();
196 :
197 6 : int task_id() const { return task_id_; }
198 6 : uint32_t instance_id() const { return instance_id_; }
199 : const Queue *queue() const { return &request_queue_; }
200 8 : size_t Size() const { return session_endpoint_map_.size(); }
201 : friend class FlowStatsManager;
202 : friend class SessionStatsCollectorObject;
203 : protected:
204 : virtual void DispatchSessionMsg(const std::vector<SessionEndpoint> &lst);
205 : private:
206 : #define CheckFlowLogging(logged) { \
207 : if (logged) { \
208 : return true; \
209 : } \
210 : }
211 : int ComputeSloRate(int rate, SecurityLoggingObject *slo) const;
212 : bool FetchFlowStats(SessionFlowStatsInfo *info,
213 : SessionFlowStatsParams *params) const;
214 : uint64_t threshold() const;
215 : bool IsSamplingEnabled() const;
216 : bool SampleSession(SessionPreAggInfo::SessionMap::iterator session_map_iter,
217 : SessionStatsParams *params) const;
218 : bool SessionStatsChangedLocked
219 : (SessionPreAggInfo::SessionMap::iterator session_map_iter,
220 : SessionStatsParams *params) const;
221 : bool SessionStatsChangedUnlocked
222 : (SessionPreAggInfo::SessionMap::iterator session_map_iter,
223 : SessionStatsParams *params) const;
224 : bool ProcessSessionEndpoint(const SessionEndpointMap::iterator &it);
225 : uint64_t GetUpdatedSessionFlowBytes(uint64_t info_bytes,
226 : uint64_t k_flow_bytes) const;
227 : uint64_t GetUpdatedSessionFlowPackets(uint64_t info_packets,
228 : uint64_t k_flow_pkts) const;
229 : void FillSessionEvictStats
230 : (SessionPreAggInfo::SessionMap::iterator session_map_iter,
231 : SessionInfo *session_info, bool is_sampling, bool is_logging) const;
232 : void FillSessionFlowStats(const SessionFlowStatsParams &stats,
233 : SessionFlowInfo *flow_info,
234 : bool is_sampling,
235 : bool is_logging) const;
236 : void FillSessionFlowInfo(const SessionFlowStatsInfo &session_flow,
237 : const SessionStatsInfo &sinfo,
238 : const SessionFlowExportInfo &einfo,
239 : SessionFlowInfo *flow_info) const;
240 : void CopyFlowInfoInternal(SessionFlowExportInfo *info,
241 : const boost::uuids::uuid &u,
242 : FlowEntry *fe) const;
243 : void CopyFlowInfo(SessionStatsInfo &session,
244 : const RevFlowDepParams *params);
245 : void UpdateAggregateStats(const SessionInfo &sinfo,
246 : SessionAggInfo *agg_info,
247 : bool is_sampling, bool is_logging) const;
248 : void FillSessionInfoLocked
249 : (SessionPreAggInfo::SessionMap::iterator session_map_iter,
250 : const SessionStatsParams &stats, SessionInfo *session_info,
251 : SessionIpPort *session_key, bool is_sampling, bool is_logging) const;
252 : void FillSessionInfoUnlocked
253 : (SessionPreAggInfo::SessionMap::iterator session_map_iter,
254 : const SessionStatsParams &stats, SessionInfo *session_info,
255 : SessionIpPort *session_key,
256 : const RevFlowDepParams *params,
257 : bool read_flow, bool is_sampling, bool is_logging) const;
258 : void FillSessionAggInfo(SessionEndpointInfo::SessionAggMap::iterator it,
259 : SessionIpPortProtocol *session_agg_key) const;
260 : void FillSessionEndpoint(SessionEndpointMap::iterator it,
261 : SessionEndpoint *session_ep) const;
262 : void FillSessionTags(const TagList &list, SessionEndpoint *ep) const;
263 : void FillSessionRemoteTags(const TagList &list, SessionEndpoint *ep) const;
264 : static uint64_t GetCurrentTime();
265 : void UpdateSessionFlowStatsInfo(FlowEntry* fe,
266 : SessionFlowStatsInfo *session_flow) const;
267 : void UpdateSessionStatsInfo(FlowEntry* fe, uint64_t setup_time,
268 : SessionStatsInfo *session) const;
269 : void AddSession(FlowEntry* fe, uint64_t setup_time);
270 : void DeleteSession(FlowEntry* fe, const boost::uuids::uuid &del_uuid,
271 : uint64_t teardown_time,
272 : const RevFlowDepParams *params);
273 : void EvictedSessionStatsUpdate(const FlowEntryPtr &flow,
274 : uint32_t bytes,
275 : uint32_t packets,
276 : uint32_t oflow_bytes,
277 : const boost::uuids::uuid &u);
278 : bool GetSessionKey(FlowEntry* fe, SessionAggKey &session_agg_key,
279 : SessionKey &session_key,
280 : SessionEndpointKey &session_endpoint_key);
281 : void AddFlowToSessionMap(FlowEntry *fe,
282 : SessionKey session_key,
283 : SessionAggKey session_agg_key,
284 : SessionEndpointKey session_endpoint_key);
285 : void DeleteFlowToSessionMap(FlowEntry *fe);
286 : void Shutdown();
287 : void RegisterDBClients();
288 : void AddEvent(const FlowEntryPtr &flow);
289 : void DeleteEvent(const FlowEntryPtr &flow, const RevFlowDepParams ¶ms);
290 : void UpdateSessionStatsEvent(const FlowEntryPtr &flow,
291 : uint32_t bytes,
292 : uint32_t packets,
293 : uint32_t oflow_bytes,
294 : const boost::uuids::uuid &u);
295 : bool RequestHandlerEntry();
296 : void RequestHandlerExit(bool done);
297 : bool RequestHandler(boost::shared_ptr<SessionStatsReq> req);
298 : void EnqueueSessionMsg();
299 : void DispatchPendingSessionMsg();
300 : uint8_t GetSessionMsgIdx();
301 :
302 : bool UpdateSloMatchRuleEntry(const boost::uuids::uuid &slo_uuid,
303 : const std::string &match_uuid,
304 : bool *match);
305 : bool CheckPolicyMatch(const SessionSloRuleMap &map,
306 : const std::string &policy_uuid,
307 : const bool &deleted_flag,
308 : bool *match,
309 : const bool &exported_once);
310 : bool FindSloMatchRule(const SessionSloRuleMap &map,
311 : const std::string &fw_policy_uuid,
312 : const std::string &nw_policy_uuid,
313 : const std::string &sg_policy_uuid,
314 : const bool &deleted_flag,
315 : bool *match,
316 : const bool &exported_once);
317 :
318 : void GetPolicyIdFromFlow(const FlowEntry *fe,
319 : std::string &fw_policy_uuid,
320 : std::string &nw_policy_uuid,
321 : std::string &sg_policy_uuid);
322 :
323 : void GetPolicyIdFromDeletedFlow(const SessionFlowExportInfo& flow_info,
324 : std::string& fw_policy_uuid,
325 : std::string& nw_policy_uuid,
326 : std::string& sg_policy_uuid);
327 :
328 : bool MatchSloForFlow(const SessionStatsInfo &stats_info,
329 : const FlowEntry *fe,
330 : const std::string& fw_policy_uuid,
331 : const std::string& nw_policy_uuid,
332 : const std::string& sg_policy_uuid,
333 : const bool &deleted_flag,
334 : bool *logged,
335 : const bool &exported_once);
336 :
337 : void BuildSloList(const SessionStatsInfo &stats_info,
338 : const FlowEntry *fe,
339 : SessionSloRuleMap *global_session_slo_rule_map,
340 : SessionSloRuleMap *vmi_session_slo_rule_map,
341 : SessionSloRuleMap *vn_session_slo_rule_map);
342 : void MakeSloList(const FlowEntry *fe,
343 : SessionSloRuleMap *vmi_session_slo_rule_map,
344 : SessionSloRuleMap *vn_session_slo_rule_map);
345 :
346 : bool FlowLogging(const SessionStatsInfo &stats_info,
347 : const FlowEntry *fe,
348 : bool *logged,
349 : const bool &exported_once);
350 :
351 : bool DeletedFlowLogging(const SessionStatsInfo &stats_info,
352 : const SessionFlowExportInfo &flow_info,
353 : bool *logged,
354 : const bool &exported_once);
355 :
356 : bool HandleDeletedFlowLogging(const SessionStatsInfo &stats_info);
357 : bool HandleFlowLogging(const SessionStatsInfo &stats_info);
358 : bool CheckSessionLogging(const SessionStatsInfo &stats_info);
359 : void AddSloList(const UuidList &slo_list, SessionSloRuleMap *slo_rule_map);
360 : void AddSloEntry(const boost::uuids::uuid &uuid,
361 : SessionSloRuleMap *slo_rule_map);
362 : void AddSloEntryRules(SecurityLoggingObject *slo,
363 : SessionSloRuleMap *slo_rule_map);
364 : void AddSloFirewallPolicies(SecurityLoggingObject *slo,
365 : SessionSloRuleMap *r_map);
366 : void AddSloFirewallRules(SecurityLoggingObject *slo,
367 : SessionSloRuleMap *rule_map);
368 : void AddSloRules(
369 : const std::vector<autogen::SecurityLoggingObjectRuleEntryType> &list,
370 : SecurityLoggingObject *slo,
371 : SessionSloRuleMap *slo_rule_map);
372 : void AddSessionSloRuleEntry(const std::string &uuid, int rate,
373 : SecurityLoggingObject *slo,
374 : SessionSloRuleMap *slo_rule_map);
375 : void SloNotify(DBTablePartBase *partition, DBEntryBase *e);
376 : void UpdateSloStateRules(SecurityLoggingObject *slo,
377 : SessionSloState *state);
378 : bool CheckAndDeleteSessionStatsFlow(
379 : SessionPreAggInfo::SessionMap::iterator session_map_iter);
380 :
381 : AgentUveBase *agent_uve_;
382 : int task_id_;
383 : SessionEndpointKey session_ep_iteration_key_;
384 : SessionAggKey session_agg_iteration_key_;
385 : SessionKey session_iteration_key_;
386 : SessionEndpointMap session_endpoint_map_;
387 : FlowSessionMap flow_session_map_;
388 : Queue request_queue_;
389 : std::vector<SessionEndpoint> session_msg_list_;
390 : uint8_t session_msg_index_;
391 : uint32_t instance_id_;
392 : FlowStatsManager *flow_stats_manager_;
393 : SessionStatsCollectorObject *parent_;
394 : SessionTask *session_task_;
395 : // Cached UTC Time stamp
396 : // The timestamp is taken once on SessionStatsCollector::RequestHandlerEntry()
397 : // and used for all requests in current run
398 : uint64_t current_time_;
399 : uint64_t session_task_starts_;
400 : uint32_t session_ep_visited_;
401 : DBTable::ListenerId slo_listener_id_;
402 : DISALLOW_COPY_AND_ASSIGN(SessionStatsCollector);
403 : };
404 :
405 : class SessionStatsCollectorObject {
406 : public:
407 : static const int kMaxSessionCollectors = 1;
408 : typedef boost::shared_ptr<SessionStatsCollector> SessionStatsCollectorPtr;
409 : SessionStatsCollectorObject(Agent *agent, FlowStatsManager *mgr);
410 : SessionStatsCollector* GetCollector(uint8_t idx) const;
411 : void SetExpiryTime(int time);
412 : int GetExpiryTime() const;
413 : SessionStatsCollector* FlowToCollector(const FlowEntry *flow);
414 : void Shutdown();
415 : size_t Size() const;
416 : void RegisterDBClients();
417 : private:
418 : SessionStatsCollectorPtr collectors[kMaxSessionCollectors];
419 : DISALLOW_COPY_AND_ASSIGN(SessionStatsCollectorObject);
420 : };
421 :
422 : class SessionStatsReq {
423 : public:
424 : enum Event {
425 : INVALID,
426 : ADD_SESSION,
427 : DELETE_SESSION,
428 : UPDATE_SESSION_STATS,
429 : };
430 :
431 230 : SessionStatsReq(Event ev, const FlowEntryPtr &flow, uint64_t time):
432 230 : event_(ev), flow_(flow), time_(time) {
433 230 : }
434 144 : SessionStatsReq(Event ev, const FlowEntryPtr &flow, uint64_t time,
435 144 : const RevFlowDepParams &p) :
436 144 : event_(ev), flow_(flow), time_(time), params_(p) {
437 144 : }
438 0 : SessionStatsReq(Event event, const FlowEntryPtr &flow, uint32_t bytes,
439 : uint32_t packets, uint32_t oflow_bytes,
440 0 : const boost::uuids::uuid &u) :
441 0 : event_(event), flow_(flow), bytes_(bytes), packets_(packets),
442 0 : oflow_bytes_(oflow_bytes), uuid_(u) {
443 0 : }
444 :
445 374 : ~SessionStatsReq() { }
446 :
447 374 : Event event() const { return event_; }
448 374 : FlowEntry* flow() const { return flow_.get(); }
449 : FlowEntry* reverse_flow() const;
450 374 : uint64_t time() const { return time_; }
451 144 : const RevFlowDepParams& params() const { return params_; }
452 0 : uint32_t bytes() const { return bytes_;}
453 0 : uint32_t packets() const { return packets_;}
454 0 : uint32_t oflow_bytes() const { return oflow_bytes_;}
455 0 : boost::uuids::uuid uuid() const { return uuid_; }
456 :
457 : private:
458 : Event event_;
459 : FlowEntryPtr flow_;
460 : uint64_t time_;
461 : RevFlowDepParams params_;
462 : uint32_t bytes_;
463 : uint32_t packets_;
464 : uint32_t oflow_bytes_;
465 : boost::uuids::uuid uuid_;
466 : DISALLOW_COPY_AND_ASSIGN(SessionStatsReq);
467 : };
468 :
469 : class FlowToSessionMap {
470 : public:
471 220 : FlowToSessionMap(SessionKey &session_key,
472 : SessionAggKey &session_agg_key,
473 220 : SessionEndpointKey &session_endpoint_key) :
474 220 : session_key_(session_key),
475 220 : session_agg_key_(session_agg_key),
476 220 : session_endpoint_key_(session_endpoint_key) {
477 220 : }
478 : bool IsEqual(FlowToSessionMap &rhs);
479 345 : SessionKey session_key() { return session_key_; }
480 217 : SessionAggKey session_agg_key() { return session_agg_key_; }
481 217 : SessionEndpointKey session_endpoint_key() { return session_endpoint_key_; }
482 : private:
483 : SessionKey session_key_;
484 : SessionAggKey session_agg_key_;
485 : SessionEndpointKey session_endpoint_key_;
486 : };
487 :
488 : struct SessionSloRuleEntry {
489 : public:
490 0 : SessionSloRuleEntry(int rate, const boost::uuids::uuid &uuid):
491 0 : rate(rate), slo_uuid(uuid) {}
492 :
493 : int rate;
494 : boost::uuids::uuid slo_uuid;
495 : };
496 :
497 : struct SessionSloRuleState {
498 : public:
499 : int rate;
500 : int ref_count;
501 : };
502 :
503 : class SessionSloState : public DBState {
504 : public:
505 : typedef std::map<std::string, SessionSloRuleState> SessionSloRuleStateMap;
506 : void DeleteSessionSloStateRuleEntry(std::string uuid);
507 : void UpdateSessionSloStateRuleEntry(std::string uuid, int rate);
508 : bool UpdateSessionSloStateRuleRefCount(const std::string &uuid, bool *matc);
509 0 : SessionSloState() {}
510 0 : ~SessionSloState() {
511 0 : session_rule_state_map_.clear();
512 0 : }
513 : private:
514 : SessionSloRuleStateMap session_rule_state_map_;
515 : };
516 :
517 : #endif //vnsw_agent_session_stats_collector_h
|