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