Skip to content

Commit

Permalink
Send number of flow hits for a given ACL rule in Interface and VN Uves.
Browse files Browse the repository at this point in the history
The number of flows matching a SG rule is sent in Interface UVE. The number of flows
matching Network Policy rule is sent in VN Uve.

Move UUID generation for flow from FlowStatsCollection module to Pkt module. Pkt
module will send information about flows matching a given ACL rule as  a message to
UVE module.  UVE module will build rule lists for interface and VN and send
respective UVEs periodically if there are any changes.

Change-Id: I87fd01b693d3b43c1ce272fa871eb350455c89d9
Partial-Bug: #1545818
  • Loading branch information
ashoksr committed Feb 22, 2016
1 parent e26ee84 commit 5646f96
Show file tree
Hide file tree
Showing 17 changed files with 403 additions and 12 deletions.
37 changes: 36 additions & 1 deletion src/vnsw/agent/pkt/flow_mgmt.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
#include "pkt/flow_mgmt.h"
#include "pkt/flow_mgmt_request.h"
#include "pkt/flow_mgmt_dbclient.h"
#include "uve/flow_ace_stats_request.h"
#include "uve/agent_uve_stats.h"
#include "vrouter/flow_stats/flow_stats_collector.h"
const string FlowMgmtManager::kFlowMgmtTask = "Flow::Management";

Expand Down Expand Up @@ -432,12 +434,42 @@ void FlowMgmtManager::MakeFlowMgmtKeyTree(FlowEntry *flow,
}
}

void FlowMgmtManager::EnqueueUveAddEvent(const FlowEntry *flow) const {
AgentUveStats *uve = dynamic_cast<AgentUveStats *>(agent_->uve());
if (uve) {
const Interface *itf = flow->intf_entry();
const VmInterface *vmi = dynamic_cast<const VmInterface *>(itf);
const VnEntry *vn = flow->vn_entry();
string vn_name = vn? vn->GetName() : "";
string itf_name = vmi? vmi->cfg_name() : "";
if ((!itf_name.empty() && !flow->sg_rule_uuid().empty()) ||
(!vn_name.empty() && !flow->nw_ace_uuid().empty())) {
boost::shared_ptr<FlowAceStatsRequest> req(new FlowAceStatsRequest
(FlowAceStatsRequest::ADD_FLOW, flow->uuid(), itf_name,
flow->sg_rule_uuid(), vn_name, flow->nw_ace_uuid()));
uve->stats_manager()->EnqueueEvent(req);
}
}
}

void FlowMgmtManager::EnqueueUveDeleteEvent(const FlowEntry *flow) const {
AgentUveStats *uve = dynamic_cast<AgentUveStats *>(agent_->uve());
if (uve) {
boost::shared_ptr<FlowAceStatsRequest> req(new FlowAceStatsRequest
(FlowAceStatsRequest::DELETE_FLOW, flow->uuid()));
uve->stats_manager()->EnqueueEvent(req);
}
}

void FlowMgmtManager::AddFlow(FlowEntryPtr &flow) {
LogFlow(flow.get(), "ADD");

//Enqueue Add request to flow-stats-collector
agent_->flow_stats_manager()->AddEvent(flow);

//Enqueue Add request to UVE module for ACE stats
EnqueueUveAddEvent(flow.get());

// Trace the flow add/change
FlowMgmtKeyTree new_tree;
MakeFlowMgmtKeyTree(flow.get(), &new_tree);
Expand Down Expand Up @@ -505,7 +537,10 @@ void FlowMgmtManager::DeleteFlow(FlowEntryPtr &flow) {
return;

//Enqueue Delete request to flow-stats-collector
agent_->flow_stats_manager()->DeleteEvent(flow);
agent_->flow_stats_manager()->DeleteEvent(flow.get());

//Enqueue Add request to UVE module for ACE stats
EnqueueUveDeleteEvent(flow.get());

FlowMgmtKeyTree *old_tree = &old_info->tree_;
assert(old_tree);
Expand Down
2 changes: 2 additions & 0 deletions src/vnsw/agent/pkt/flow_mgmt.h
Original file line number Diff line number Diff line change
Expand Up @@ -1042,6 +1042,8 @@ class FlowMgmtManager {
void DisableWorkQueue(bool disable) { request_queue_.set_disable(disable); }
void BgpAsAServiceNotify(const boost::uuids::uuid &vm_uuid,
uint32_t source_port);
void EnqueueUveAddEvent(const FlowEntry *flow) const;
void EnqueueUveDeleteEvent(const FlowEntry *flow) const;
private:
// Handle Add/Change of a flow. Builds FlowMgmtKeyTree for all objects
void AddFlow(FlowEntryPtr &flow);
Expand Down
51 changes: 51 additions & 0 deletions src/vnsw/agent/uve/flow_ace_stats_request.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* Copyright (c) 2016 Juniper Networks, Inc. All rights reserved.
*/
#ifndef __AGENT_FLOW_ACE_STATS_REQUEST_H__
#define __AGENT_FLOW_ACE_STATS_REQUEST_H__

#include "pkt/flow_table.h"
#include "pkt/flow_event.h"

////////////////////////////////////////////////////////////////////////////
// Request to the Uve module for Ace Stats
////////////////////////////////////////////////////////////////////////////
class FlowAceStatsRequest {
public:
enum Event {
INVALID,
ADD_FLOW,
DELETE_FLOW
};

FlowAceStatsRequest(Event event, const boost::uuids::uuid &u,
const std::string &intf, const std::string &sg_rule,
const std::string &vn, const std::string &nw_ace) :
event_(event), uuid_(u), interface_(intf), sg_rule_uuid_(sg_rule),
vn_(vn), nw_ace_uuid_(nw_ace) {
}

FlowAceStatsRequest(Event event, const boost::uuids::uuid &u) :
event_(event), uuid_(u) {
}

~FlowAceStatsRequest() { }

Event event() const { return event_; }
const boost::uuids::uuid &uuid() const { return uuid_; }
const std::string &interface() const { return interface_; }
const std::string &sg_rule_uuid() const { return sg_rule_uuid_; }
const std::string &vn() const { return vn_; }
const std::string &nw_ace_uuid() const { return nw_ace_uuid_; }

private:
Event event_;
boost::uuids::uuid uuid_;
std::string interface_;
std::string sg_rule_uuid_;
std::string vn_;
std::string nw_ace_uuid_;

DISALLOW_COPY_AND_ASSIGN(FlowAceStatsRequest);
};
#endif // __AGENT_FLOW_ACE_STATS_REQUEST_H__
9 changes: 9 additions & 0 deletions src/vnsw/agent/uve/interface.sandesh
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,14 @@ struct VmHealthCheckInstance {
4: string status;
}

/**
* Number of flow hits for a given SG ACL Rule
*/
struct SgAclRuleStats {
1: string rule;
2: u64 count;
}

/**
* Sandesh definition for vm interface in agent
*/
Expand Down Expand Up @@ -74,6 +82,7 @@ struct UveVMInterfaceAgent {
22: optional bool ip4_active;
23: optional bool is_health_check_active;
24: optional list<VmHealthCheckInstance> health_check_instance_list;
25: optional list<SgAclRuleStats> sg_rule_stats (tags=".rule");
}

/**
Expand Down
21 changes: 21 additions & 0 deletions src/vnsw/agent/uve/interface_uve_stats_table.cc
Original file line number Diff line number Diff line change
Expand Up @@ -202,3 +202,24 @@ InterfaceUveTable::FloatingIp * InterfaceUveStatsTable::FipEntry
UveInterfaceEntry *entry = intf_it->second.get();
return entry->FipEntry(fip, vn);
}

void InterfaceUveStatsTable::IncrInterfaceAceStats(const std::string &itf,
const std::string &u) {
if (itf.empty() || u.empty()) {
return;
}
InterfaceMap::iterator intf_it = interface_tree_.find(itf);

if (intf_it != interface_tree_.end()) {
UveInterfaceEntry *entry = intf_it->second.get();
entry->UpdateInterfaceAceStats(u);
}
}

void InterfaceUveStatsTable::SendInterfaceAceStats(const string &name,
UveInterfaceEntry *entry) {
UveVMInterfaceAgent uve;
if (entry->FrameInterfaceAceStatsMsg(name, &uve)) {
DispatchInterfaceMsg(uve);
}
}
2 changes: 2 additions & 0 deletions src/vnsw/agent/uve/interface_uve_stats_table.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ class InterfaceUveStatsTable : public InterfaceUveTable {
(uint32_t fip, const string &vn, Interface *intf);
void UpdatePortBitmap
(const string &name, uint8_t proto, uint16_t sport, uint16_t dport);
void IncrInterfaceAceStats(const std::string &itf, const std::string &u);
void SendInterfaceAceStats(const string &name, UveInterfaceEntry *entry);

private:
void SendInterfaceStatsMsg(UveInterfaceEntry* entry);
Expand Down
66 changes: 61 additions & 5 deletions src/vnsw/agent/uve/interface_uve_table.cc
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,22 @@ bool InterfaceUveTable::TimerExpiry() {
entry->renewed_ = false;
entry->changed_ = false;
SendInterfaceMsg(cfg_name, entry);
// Send Interface ACE stats
SendInterfaceAceStats(cfg_name, entry);
}
} else if (entry->changed_) {
SendInterfaceMsg(cfg_name, entry);
entry->changed_ = false;
/* Clear renew flag to be on safer side. Not really required */
entry->renewed_ = false;
} else {
if (entry->changed_) {
SendInterfaceMsg(cfg_name, entry);
entry->changed_ = false;
/* Clear renew flag to be on safer side. Not really required */
entry->renewed_ = false;
}
// Send Interface ACE stats
SendInterfaceAceStats(cfg_name, entry);
}
}


if (it == interface_tree_.end()) {
timer_last_visited_ = "";
set_expiry_time(agent_->uve()->default_interval());
Expand Down Expand Up @@ -170,7 +177,9 @@ void InterfaceUveTable::UveInterfaceEntry::Reset() {
port_bitmap_.Reset();
prev_fip_tree_.clear();
fip_tree_.clear();
ace_set_.clear();

ace_stats_changed_ = false;
deleted_ = true;
renewed_ = false;
}
Expand Down Expand Up @@ -561,3 +570,50 @@ void InterfaceUveTable::UveInterfaceEntry::RemoveFloatingIp
}
}

void InterfaceUveTable::UveInterfaceEntry::UpdateInterfaceAceStats
(const std::string &ace_uuid) {
AceStats key(ace_uuid);
ace_stats_changed_ = true;
AceStatsSet::const_iterator it = ace_set_.find(key);
if (it != ace_set_.end()) {
it->count++;
return;
}
key.count = 1;
ace_set_.insert(key);
}

bool InterfaceUveTable::UveInterfaceEntry::FrameInterfaceAceStatsMsg
(const std::string &name, UveVMInterfaceAgent *s_intf) {
if (!ace_stats_changed_) {
return false;
}
std::vector<SgAclRuleStats> list;
AceStatsSet::iterator it = ace_set_.begin();
bool changed = false;
while (it != ace_set_.end()) {
SgAclRuleStats item;
item.set_rule(it->ace_uuid);
uint64_t diff_count = it->count - it->prev_count;
item.set_count(diff_count);
//Update prev_count
it->prev_count = it->count;
list.push_back(item);
++it;
/* If diff_count is non-zero for any rule entry, we send the entire
* list */
if (diff_count) {
changed = true;
}
}
/* If all the entries in the list has 0 diff_stats, then UVE won't be
* sent */
if (changed) {
s_intf->set_name(name);
SetVnVmInfo(s_intf);
s_intf->set_sg_rule_stats(list);
ace_stats_changed_ = false;
return true;
}
return false;
}
20 changes: 20 additions & 0 deletions src/vnsw/agent/uve/interface_uve_table.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,18 @@ class InterfaceUveTable {
};
typedef std::set<FloatingIpPtr, FloatingIpCmp> FloatingIpSet;

struct AceStats {
const std::string ace_uuid;
mutable uint64_t count;
mutable uint64_t prev_count;
AceStats(const std::string &ace) : ace_uuid(ace), count(0),
prev_count(0) {
}
bool operator<(const AceStats &rhs) const {
return ace_uuid < rhs.ace_uuid;
}
};
typedef std::set<AceStats> AceStatsSet;
struct UveInterfaceEntry {
const VmInterface *intf_;
boost::uuids::uuid uuid_;
Expand All @@ -100,7 +112,9 @@ class InterfaceUveTable {
bool changed_;
bool deleted_;
bool renewed_;
bool ace_stats_changed_;
UveVMInterfaceAgent uve_info_;
AceStatsSet ace_set_;
/* For exclusion between Agent::StatsCollector and Agent::Uve tasks */
tbb::mutex mutex_;

Expand All @@ -124,13 +138,16 @@ class InterfaceUveTable {
const std::string &vn);
bool FrameInterfaceMsg(const std::string &name,
UveVMInterfaceAgent *s_intf) const;
bool FrameInterfaceAceStatsMsg(const std::string &name,
UveVMInterfaceAgent *s_intf);
bool GetVmInterfaceGateway(const VmInterface *vm_intf,
std::string &gw) const;
bool FipAggStatsChanged(const vector<VmFloatingIPStats> &list) const;
bool PortBitmapChanged(const PortBucketBitmap &bmap) const;
bool InBandChanged(uint64_t in_band) const;
bool OutBandChanged(uint64_t out_band) const;
void SetVnVmInfo(UveVMInterfaceAgent *uve) const;
void UpdateInterfaceAceStats(const std::string &ace_uuid);
void Reset();
};
typedef boost::shared_ptr<UveInterfaceEntry> UveInterfaceEntryPtr;
Expand All @@ -144,6 +161,9 @@ class InterfaceUveTable {
void Shutdown(void);
virtual void DispatchInterfaceMsg(const UveVMInterfaceAgent &uve);
bool TimerExpiry();
virtual void SendInterfaceAceStats(const string &name,
UveInterfaceEntry *entry) {
}

protected:
void SendInterfaceDeleteMsg(const std::string &config_name);
Expand Down

0 comments on commit 5646f96

Please sign in to comment.