Skip to content

Commit

Permalink
Merge "Send number of flow hits for a given ACL rule in Interface and…
Browse files Browse the repository at this point in the history
… VN Uves." into R3.0
  • Loading branch information
Zuul authored and opencontrail-ci-admin committed Feb 22, 2016
2 parents c108acc + 5646f96 commit c237b95
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
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
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
@@ -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
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
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
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
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
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 c237b95

Please sign in to comment.