-
Notifications
You must be signed in to change notification settings - Fork 390
/
flow_stats_manager.h
177 lines (146 loc) · 5.55 KB
/
flow_stats_manager.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
/*
* Copyright (c) 2015 Juniper Networks, Inc. All rights reserved.
*/
#ifndef vnsw_agent_flow_stats_maanger_h
#define vnsw_agent_flow_stats_maanger_h
#include <cmn/agent_cmn.h>
#include <cmn/index_vector.h>
#include <uve/stats_collector.h>
#include <uve/interface_uve_stats_table.h>
#include <pkt/flow_table.h>
#include <vrouter/ksync/flowtable_ksync.h>
#include <sandesh/common/flow_types.h>
class FlowStatsCollector;
struct FlowAgingTableKey {
FlowAgingTableKey(const uint8_t &protocol, const uint16_t &dst_port):
proto(protocol), port(dst_port) {}
bool operator==(const FlowAgingTableKey &rhs) const {
return (proto == rhs.proto && port == rhs.port);
}
bool operator<(const FlowAgingTableKey &rhs) const {
if (proto != rhs.proto) {
return proto < rhs.proto;
}
return port < rhs.port;
}
uint8_t proto;
uint16_t port;
};
struct FlowStatsCollectorReq {
enum Event {
INVALID,
ADD_FLOW_STATS_COLLECTOR,
DELETE_FLOW_STATS_COLLECTOR,
FREE_FLOW_STATS_COLLECTOR,
};
FlowStatsCollectorReq(Event ev, const FlowAgingTableKey &k,
uint64_t interval, uint64_t timeout,
bool user_cfgd) :
event(ev), key(k), flow_stats_interval(interval),
flow_cache_timeout(timeout), user_configured(user_cfgd) {}
FlowStatsCollectorReq(Event ev, const FlowAgingTableKey &k):
event(ev), key(k) {}
Event event;
FlowAgingTableKey key;
uint64_t flow_stats_interval;
uint64_t flow_cache_timeout;
bool user_configured;
};
class FlowStatsManager {
public:
static const uint8_t kCatchAllProto = 0x0;
static const uint64_t FlowThresoldUpdateTime = 1000 * 2;
static const uint32_t kDefaultFlowSamplingThreshold = 500;
typedef boost::shared_ptr<FlowStatsCollector> FlowAgingTablePtr;
typedef std::map<const FlowAgingTableKey, FlowAgingTablePtr>
FlowAgingTableMap;
typedef std::pair<const FlowAgingTableKey, FlowAgingTablePtr>
FlowAgingTableEntry;
FlowStatsManager(Agent *agent);
~FlowStatsManager();
Agent* agent() { return agent_; }
FlowStatsCollector* default_flow_stats_collector() {
return default_flow_stats_collector_.get();
}
FlowStatsCollector* tcp_flow_stats_collector() {
return protocol_list_[IPPROTO_TCP];
}
//Add protocol + port based flow aging table
void Add(const FlowAgingTableKey &key,
uint64_t flow_stats_interval,
uint64_t flow_cache_timeout, bool user_configured);
void Delete(const FlowAgingTableKey &key);
void Free(const FlowAgingTableKey &key);
//Add flow entry to particular aging table
void AddEvent(FlowEntryPtr &flow);
void DeleteEvent(const FlowEntryPtr &flow);
void FlowIndexUpdateEvent(const FlowEntryPtr &flow);
void UpdateStatsEvent(const FlowEntryPtr &flow, uint32_t bytes,
uint32_t packets, uint32_t oflow_bytes);
void Init(uint64_t flow_stats_interval, uint64_t flow_cache_timeout);
void Shutdown();
FlowAgingTableMap::iterator begin() {
return flow_aging_table_map_.begin();
}
FlowAgingTableMap::iterator end() {
return flow_aging_table_map_.end();
}
FlowStatsCollector* GetFlowStatsCollector(const FlowKey &key) const;
const FlowStatsCollector* Find(uint32_t proto, uint32_t port) const;
bool RequestHandler(boost::shared_ptr<FlowStatsCollectorReq> req);
void AddReqHandler(boost::shared_ptr<FlowStatsCollectorReq> req);
void DeleteReqHandler(boost::shared_ptr<FlowStatsCollectorReq> req);
void FreeReqHandler(boost::shared_ptr<FlowStatsCollectorReq> req);
uint32_t flow_export_rate() const {
return flow_export_rate_;
}
uint32_t flow_export_count() const {
return flow_export_count_;
}
void set_flow_export_count(uint32_t count) {
flow_export_count_ = count;
}
uint32_t flow_export_count_reset() {
return flow_export_count_.fetch_and_store(0);
}
uint32_t flow_export_msg_drops() const {
return flow_export_msg_drops_;
}
void set_flow_export_msg_drops(uint32_t count) {
flow_export_msg_drops_ = count;
}
uint32_t threshold() const { return threshold_;}
bool delete_short_flow() const {
return delete_short_flow_;
}
void set_delete_short_flow(bool val) {
delete_short_flow_ = val;
}
static void FlowStatsReqHandler(Agent *agent, uint32_t proto,
uint32_t port,
uint64_t protocol);
void FreeIndex(uint32_t idx);
friend class AgentUtXmlFlowThreshold;
friend class AgentUtXmlFlowThresholdValidate;
private:
friend class FlowStatsCollectorReq;
friend class FlowStatsCollector;
bool UpdateFlowThreshold(void);
void UpdateThreshold(uint32_t new_value);
Agent *agent_;
WorkQueue<boost::shared_ptr<FlowStatsCollectorReq> > request_queue_;
FlowAgingTableMap flow_aging_table_map_;
FlowAgingTablePtr default_flow_stats_collector_;
tbb::atomic<uint32_t> flow_export_count_;
uint64_t prev_flow_export_rate_compute_time_;
uint32_t flow_export_rate_;
uint32_t threshold_;
tbb::atomic<uint32_t> flow_export_msg_drops_;
uint32_t prev_cfg_flow_export_rate_;
Timer* timer_;
bool delete_short_flow_;
//Protocol based array for minimal tree comparision
FlowStatsCollector* protocol_list_[256];
IndexVector<FlowStatsCollector> instance_table_;
};
#endif //vnsw_agent_flow_stats_manager_h