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_interface_uve_table_h
7 : #define vnsw_agent_interface_uve_table_h
8 :
9 : #include <string>
10 : #include <vector>
11 : #include <set>
12 : #include <map>
13 : #include <mutex>
14 :
15 : #include <boost/scoped_ptr.hpp>
16 : #include <boost/shared_ptr.hpp>
17 : #include <interface_types.h>
18 : #include <uve/l4_port_bitmap.h>
19 : #include <oper/vm.h>
20 : #include <oper/peer.h>
21 : #include <cmn/index_vector.h>
22 : #include <oper/interface_common.h>
23 : #include <vnsw/agent/uve/uve_types.h>
24 : #include <uve/flow_uve_stats_request.h>
25 :
26 : /* Structure used to pass Endpoint data from FlowStatsCollector to UVE module */
27 : struct EndpointStatsInfo {
28 : const VmInterface *vmi;
29 : TagList local_tagset;
30 : std::string policy; //has policy-name and rule-uuid
31 : std::string local_vn;
32 : std::string remote_vn;
33 : TagList remote_tagset;
34 : std::string remote_prefix;
35 : std::string action;
36 : uint64_t diff_bytes;
37 : uint64_t diff_pkts;
38 : /* The following bool field indicates diff_bytes and diff_pkts are
39 : * in_stats or out_stats */
40 : bool in_stats;
41 : /* The following bool field indicates whether endpoint data corresponds to
42 : * client session or server session.
43 : * Ingress+Forward and Egress+Reverse are client flows.
44 : * Egress+Forward and Ingress+Reverse are server flows.
45 : * in_stats or out_stats */
46 : bool client;
47 : };
48 :
49 : //The container class for objects representing VMInterface UVEs
50 : //Defines routines for storing and managing (add, delete, change and send)
51 : //VMInterface UVEs
52 : class InterfaceUveTable {
53 : public:
54 : struct UveInterfaceState :public DBState {
55 167 : UveInterfaceState(const VmInterface *intf)
56 167 : : cfg_name_(intf->cfg_name()),
57 334 : fip_list_(intf->floating_ip_list().list_) {}
58 : std::string cfg_name_;
59 : VmInterface::FloatingIpSet fip_list_;
60 : };
61 :
62 : struct FloatingIp;
63 :
64 : struct FipInfo {
65 : uint64_t bytes_;
66 : uint64_t packets_;
67 : uint32_t fip_;
68 : VmInterfaceKey fip_vmi_;
69 : bool is_local_flow_;
70 : bool is_ingress_flow_;
71 : bool is_reverse_flow_;
72 : std::string vn_;
73 : FloatingIp *rev_fip_;
74 42 : FipInfo() : bytes_(0), packets_(0), fip_(0),
75 42 : fip_vmi_(AgentKey::ADD_DEL_CHANGE, boost::uuids::nil_uuid(), ""),
76 42 : is_local_flow_(false), is_ingress_flow_(false),
77 42 : is_reverse_flow_(false), rev_fip_(NULL) {
78 42 : }
79 : };
80 : struct FloatingIp {
81 320 : FloatingIp(const IpAddress &ip, const std::string &vn)
82 320 : : family_(ip.is_v4() ? Address::INET : Address::INET6),
83 320 : fip_(ip), vn_(vn) {
84 320 : in_bytes_ = 0;
85 320 : in_packets_ = 0;
86 320 : out_bytes_ = 0;
87 320 : out_packets_ = 0;
88 320 : }
89 0 : FloatingIp(const IpAddress &ip, const std::string &vn, uint64_t in_b,
90 : uint64_t in_p, uint64_t out_b, uint64_t out_p)
91 0 : : family_(ip.is_v4() ? Address::INET : Address::INET6),
92 0 : fip_(ip), vn_(vn), in_bytes_(in_b), in_packets_(in_p),
93 0 : out_bytes_(out_b), out_packets_(out_p) {
94 0 : }
95 : void UpdateFloatingIpStats(const FipInfo &fip_info);
96 :
97 : Address::Family family_;
98 : IpAddress fip_;
99 : std::string vn_;
100 : uint64_t in_bytes_;
101 : uint64_t in_packets_;
102 : uint64_t out_bytes_;
103 : uint64_t out_packets_;
104 : };
105 : typedef boost::shared_ptr<FloatingIp> FloatingIpPtr;
106 :
107 : class FloatingIpCmp {
108 : public:
109 414 : bool operator()(const FloatingIpPtr &lhs,
110 : const FloatingIpPtr &rhs) const {
111 414 : if (lhs.get()->fip_ != rhs.get()->fip_) {
112 0 : return lhs.get()->fip_ < rhs.get()->fip_;
113 : }
114 414 : return (lhs.get()->vn_ < rhs.get()->vn_);
115 : }
116 : };
117 : typedef std::set<FloatingIpPtr, FloatingIpCmp> FloatingIpSet;
118 :
119 : struct AceStats {
120 : const std::string ace_uuid;
121 : mutable uint64_t count;
122 : mutable uint64_t prev_count;
123 169 : AceStats(const std::string &ace) : ace_uuid(ace), count(0),
124 169 : prev_count(0) {
125 169 : }
126 322 : bool operator<(const AceStats &rhs) const {
127 322 : return ace_uuid < rhs.ace_uuid;
128 : }
129 : };
130 : //Forward declaration
131 : struct UveInterfaceEntry;
132 : struct UveSecurityPolicyStats {
133 : /* We have added local_tagset here as well as at interface level. During
134 : * transient cases of change of local_tagset of VMI, we want to track
135 : * the local_tagset for which the statistics correspond to. This will
136 : * also help in retaining stats for old local_tagset when tag_sets have
137 : * changed. While export Endpoint objectlogs, always pick local_tagset
138 : * from here instead of interface level local_tagset */
139 : TagList local_tagset;
140 : TagList remote_tagset;
141 : std::string remote_prefix;
142 : std::string remote_vn;
143 : std::string local_vn;
144 : std::string action;
145 : uint64_t added;
146 : uint64_t deleted;
147 : uint64_t active;
148 : uint64_t dropped_short;
149 : uint64_t in_bytes;
150 : uint64_t in_pkts;
151 : uint64_t out_bytes;
152 : uint64_t out_pkts;
153 : uint64_t prev_in_bytes;
154 : uint64_t prev_in_pkts;
155 : uint64_t prev_out_bytes;
156 : uint64_t prev_out_pkts;
157 : uint64_t prev_added;
158 : uint64_t prev_deleted;
159 41 : UveSecurityPolicyStats(const TagList <set, const TagList &rtset,
160 : const std::string &rprefix,
161 : const std::string &rvn, const std::string &lvn,
162 41 : const std::string &action_str) :
163 41 : local_tagset(ltset), remote_tagset(rtset), remote_prefix(rprefix),
164 41 : remote_vn(rvn), local_vn(lvn), action(action_str), added(0),
165 41 : deleted(0), active(0), dropped_short(0), in_bytes(0), in_pkts(0),
166 41 : out_bytes(0), out_pkts(0) , prev_in_bytes(0) , prev_in_pkts(0),
167 41 : prev_out_bytes(0), prev_out_pkts(0), prev_added(0), prev_deleted(0){
168 41 : }
169 : };
170 : typedef boost::shared_ptr<UveSecurityPolicyStats> UveSecurityPolicyStatsPtr;
171 : struct PolicyCmp {
172 55 : bool operator() (const UveSecurityPolicyStatsPtr &lhs,
173 : const UveSecurityPolicyStatsPtr &rhs) const {
174 55 : if (lhs->local_vn.compare(rhs->local_vn) != 0) {
175 0 : return lhs->local_vn < rhs->local_vn;
176 : }
177 55 : if (lhs->remote_vn.compare(rhs->remote_vn) != 0) {
178 0 : return lhs->remote_vn < rhs->remote_vn;
179 : }
180 55 : if (lhs->local_tagset != rhs->local_tagset) {
181 0 : return lhs->local_tagset < rhs->local_tagset;
182 : }
183 55 : if (lhs->remote_tagset != rhs->remote_tagset) {
184 0 : return lhs->remote_tagset < rhs->remote_tagset;
185 : }
186 55 : return lhs->remote_prefix < rhs->remote_prefix;
187 : }
188 : };
189 : typedef std::set<UveSecurityPolicyStatsPtr, PolicyCmp>
190 : SecurityPolicyStatsSet;
191 : struct EndpointStatsContainer {
192 : SecurityPolicyStatsSet client_list;
193 : SecurityPolicyStatsSet server_list;
194 41 : SecurityPolicyStatsSet &ToList(bool client) {
195 41 : if (client) {
196 5 : return client_list;
197 : } else {
198 36 : return server_list;
199 : }
200 : }
201 : };
202 : typedef std::map<std::string, EndpointStatsContainer>
203 : SecurityPolicyStatsMap;
204 : typedef std::pair<std::string, EndpointStatsContainer>
205 : SecurityPolicyStatsPair;
206 : typedef std::set<AceStats> AceStatsSet;
207 : struct UveInterfaceEntry {
208 : const VmInterface *intf_;
209 : boost::uuids::uuid uuid_;
210 : L4PortBitmap port_bitmap_;
211 : FloatingIpSet fip_tree_;
212 : FloatingIpSet prev_fip_tree_;
213 : bool changed_;
214 : bool deleted_;
215 : bool renewed_;
216 : bool ace_stats_changed_;
217 : VMIStats uve_stats_;
218 : AceStatsSet ace_set_;
219 : TagList local_tagset_;
220 : SecurityPolicyStatsMap security_policy_stats_map_;
221 : VMITags prev_tags_uve_;
222 : /* For exclusion between kTaskFlowStatsCollector and Agent::Uve
223 : * (1) port_bitmap_ and fip_tree_ are updated by kTaskFlowStatsCollector
224 : * and read by Agent::Uve.
225 : * (2) security_policy_stats_map_ is cleared and updated by both
226 : * kTaskFlowStatsCollector and Agent::Uve
227 : * -- Agent::Uve task updates session_count
228 : * (inside security_policy_stats_map_), clears and adds entries
229 : * to security_policy_stats_map_
230 : * -- kTaskFlowStatsCollector updates stats of
231 : * security_policy_stats_map_ and resets
232 : * security_policy_stats_map_
233 : */
234 : std::mutex mutex_;
235 :
236 1062 : UveInterfaceEntry(const VmInterface *i) : intf_(i),
237 1062 : uuid_(i->GetUuid()), port_bitmap_(),
238 1062 : fip_tree_(), prev_fip_tree_(), changed_(true), deleted_(false),
239 2124 : renewed_(false), uve_stats_() { }
240 2124 : virtual ~UveInterfaceEntry() {}
241 : void UpdateFloatingIpStats(const FipInfo &fip_info);
242 : bool FillFloatingIpStats(vector<VmFloatingIPStats> &result,
243 : vector<VmFloatingIPStats> &diff_list,
244 : bool &diff_list_send);
245 : void SetStats(VmFloatingIPStats &fip, uint64_t in_bytes,
246 : uint64_t in_pkts, uint64_t out_bytes, uint64_t out_pkts) const;
247 : void SetDiffStats(VmFloatingIPStats &fip, uint64_t in_bytes,
248 : uint64_t in_pkts, uint64_t out_bytes, uint64_t out_pkts,
249 : bool &diff_list_send) const;
250 : void RemoveFloatingIp(const VmInterface::FloatingIp &fip);
251 : void AddFloatingIp(const VmInterface::FloatingIp &fip);
252 : InterfaceUveTable::FloatingIp *FipEntry(uint32_t ip,
253 : const std::string &vn);
254 : bool FrameInterfaceMsg(const std::string &name,
255 : UveVMInterfaceAgent *s_intf) const;
256 : bool FrameTagsUveMsg(Agent *agent, const std::string &name,
257 : VMITags *uve);
258 : bool FrameInterfaceAceStatsMsg(const std::string &name,
259 : VMIStats *s_intf);
260 : bool GetVmInterfaceGateway(const VmInterface *vm_intf,
261 : std::string &gw) const;
262 : bool FipAggStatsChanged(const vector<VmFloatingIPStats> &list) const;
263 : bool PortBitmapChanged(const PortBucketBitmap &bmap) const;
264 : bool InBandChanged(uint64_t in_band) const;
265 : bool OutBandChanged(uint64_t out_band) const;
266 : void SetVnVmInfo(UveVMInterfaceAgent *uve) const;
267 : void SetVMIStatsVnVm(VMIStats *uve) const;
268 : void UpdateInterfaceAceStats(const std::string &ace_uuid);
269 : void Reset();
270 : void UpdatePortBitmap(uint8_t proto, uint16_t sport, uint16_t dport);
271 : void UpdateInterfaceFwPolicyStats(const FlowUveFwPolicyInfo &info);
272 : void UpdateCounters(const FlowUveFwPolicyInfo &info,
273 : UveSecurityPolicyStats *obj);
274 : void UpdateSecurityPolicyStats(const EndpointStatsInfo &info);
275 : void UpdateSecurityPolicyStatsInternal(const EndpointStatsInfo &info,
276 : UveSecurityPolicyStats *stats);
277 : void FillEndpointStats(Agent *agent, EndpointSecurityStats *obj);
278 : void BuildInterfaceUveInfo(InterfaceUveInfo *r) const;
279 : void FillTagSetAndPolicyList(VMIStats *obj);
280 : void BuildSandeshUveTagList(const TagList &list,
281 : std::vector<SandeshUveTagInfo> *rts) const;
282 : void HandleTagListChange();
283 : void FillSecurityPolicyList(Agent *agent,
284 : const SecurityPolicyStatsSet &ilist,
285 : std::vector<SecurityPolicyFlowStats> *ol);
286 : void BuildInterfaceUveSecurityPolicyList
287 : (const SecurityPolicyStatsSet &ilist,
288 : std::vector<SandeshUveRemoteEndpoint> *olist) const;
289 : std::string GetVmName() const;
290 : };
291 : typedef boost::shared_ptr<UveInterfaceEntry> UveInterfaceEntryPtr;
292 :
293 : typedef std::map<std::string, UveInterfaceEntryPtr> InterfaceMap;
294 : typedef std::pair<std::string, UveInterfaceEntryPtr> InterfacePair;
295 :
296 : InterfaceUveTable(Agent *agent, uint32_t default_intvl);
297 : virtual ~InterfaceUveTable();
298 : void RegisterDBClients();
299 : void Shutdown(void);
300 : virtual void DispatchInterfaceMsg(const UveVMInterfaceAgent &uve);
301 : virtual void DispatchInterfaceObjectLog(EndpointSecurityStats *obj);
302 : void DispatchVMITagsMsg(const VMITags &uve) const;
303 : virtual void DispatchVMIStatsMsg(const VMIStats &uve);
304 : bool TimerExpiry();
305 0 : virtual void SendInterfaceAceStats(const string &name,
306 : UveInterfaceEntry *entry) {
307 0 : }
308 : void HandleVmiTagListChange(const std::string &name);
309 :
310 : protected:
311 : void SendInterfaceDeleteMsg(const std::string &config_name);
312 :
313 : Agent *agent_;
314 : InterfaceMap interface_tree_;
315 : /* For exclusion between kTaskFlowStatsCollector and kTaskDBExclude */
316 : std::mutex interface_tree_mutex_;
317 : private:
318 : virtual UveInterfaceEntryPtr Allocate(const VmInterface *vm);
319 : void InterfaceNotify(DBTablePartBase *partition, DBEntryBase *e);
320 : void InterfaceAddHandler(const VmInterface* intf,
321 : const VmInterface::FloatingIpSet &old_list);
322 : void InterfaceDeleteHandler(const std::string &name);
323 : void set_expiry_time(int time);
324 : void SendInterfaceMsg(const std::string &name, UveInterfaceEntry *entry);
325 :
326 : DBTableBase::ListenerId intf_listener_id_;
327 : // Last visited Interface by timer
328 : std::string timer_last_visited_;
329 : Timer *timer_;
330 : int expiry_time_;
331 : DISALLOW_COPY_AND_ASSIGN(InterfaceUveTable);
332 : };
333 :
334 : #endif // vnsw_agent_interface_uve_table_h
|