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