Skip to content

Commit

Permalink
Merge "Index flow-aging tree with FlowEntry pointer instead of UUID"
Browse files Browse the repository at this point in the history
  • Loading branch information
Zuul authored and opencontrail-ci-admin committed Apr 17, 2016
2 parents 47ef2ca + 198e68d commit ee2c099
Show file tree
Hide file tree
Showing 31 changed files with 479 additions and 639 deletions.
1 change: 0 additions & 1 deletion src/vnsw/agent/oper/test/test_xml_agent_init.cc
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@ TestClient *PhysicalDeviceTestInit(const char *init_file, bool ksync_init) {
client->Init();
client->WaitForIdle();
client->SetFlowFlushExclusionPolicy();
client->SetFlowAgeExclusionPolicy();

AsioRun();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,6 @@ TestClient *OvsTestInit(const char *init_file, bool ovs_init, bool use_ssl) {
client->Init();
client->WaitForIdle();
client->SetFlowFlushExclusionPolicy();
client->SetFlowAgeExclusionPolicy();

AsioRun();

Expand Down
52 changes: 33 additions & 19 deletions src/vnsw/agent/pkt/flow_entry.cc
Original file line number Diff line number Diff line change
Expand Up @@ -780,6 +780,24 @@ uint32_t FlowEntry::acl_assigned_vrf_index() const {
return data_.acl_assigned_vrf_index_;
}

void FlowEntry::RevFlowDepInfo(RevFlowDepParams *params) {
params->sip_ = key().src_addr;
FlowEntry *rev_flow = reverse_flow_entry();
if (rev_flow) {
params->rev_uuid_ = rev_flow->uuid();
if (key().family != Address::INET) {
return;
}
if (is_flags_set(FlowEntry::NatFlow) &&
is_flags_set(FlowEntry::IngressDir)) {
const FlowKey *nat_key = &rev_flow->key();
if (key().src_addr != nat_key->dst_addr) {
params->sip_ = nat_key->dst_addr;
}
}
}
}

static bool ShouldDrop(uint32_t action) {
if (action & TrafficAction::DROP_FLAGS)
return true;
Expand Down Expand Up @@ -2224,13 +2242,6 @@ void FlowEntry::SetAclFlowSandeshData(const AclDBEntry *acl,
fe_sandesh_data.set_source_vn_list(data_.SourceVnList());
fe_sandesh_data.set_dest_vn_list(data_.DestinationVnList());
std::vector<uint32_t> v;
if (!fsc_) {
return;
}
const FlowExportInfo *info = fsc_->FindFlowExportInfo(uuid_);
if (!info) {
return;
}
SecurityGroupList::const_iterator it;
for (it = data_.source_sg_id_l.begin();
it != data_.source_sg_id_l.end(); it++) {
Expand All @@ -2243,18 +2254,21 @@ void FlowEntry::SetAclFlowSandeshData(const AclDBEntry *acl,
v.push_back(*it);
}
fe_sandesh_data.set_dest_sg_id_l(v);
if (info) {
fe_sandesh_data.set_flow_uuid(UuidToString(info->flow_uuid()));
fe_sandesh_data.set_bytes(integerToString(info->bytes()));
fe_sandesh_data.set_packets(integerToString(info->packets()));
fe_sandesh_data.set_setup_time(
integerToString(UTCUsecToPTime(info->setup_time())));
fe_sandesh_data.set_setup_time_utc(info->setup_time());
if (info->teardown_time()) {
fe_sandesh_data.set_teardown_time(
integerToString(UTCUsecToPTime(info->teardown_time())));
} else {
fe_sandesh_data.set_teardown_time("");
fe_sandesh_data.set_flow_uuid(UuidToString(uuid()));
if (fsc_) {
const FlowExportInfo *info = fsc_->FindFlowExportInfo(this);
if (info) {
fe_sandesh_data.set_bytes(integerToString(info->bytes()));
fe_sandesh_data.set_packets(integerToString(info->packets()));
fe_sandesh_data.set_setup_time(
integerToString(UTCUsecToPTime(info->setup_time())));
fe_sandesh_data.set_setup_time_utc(info->setup_time());
if (info->teardown_time()) {
fe_sandesh_data.set_teardown_time(
integerToString(UTCUsecToPTime(info->teardown_time())));
} else {
fe_sandesh_data.set_teardown_time("");
}
}
}
fe_sandesh_data.set_current_time(integerToString(
Expand Down
20 changes: 18 additions & 2 deletions src/vnsw/agent/pkt/flow_entry.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,23 @@ class FlowEntry;
struct FlowExportInfo;
class FlowStatsCollector;

////////////////////////////////////////////////////////////////////////////
// This is helper struct to carry parameters of reverse-flow. When flow is
// being deleted, the relationship between forward and reverse flows are
// broken. However, some info of reverse flow is needed during export of flows
// for FlowStatsCollector. This information of reverse flow is carried in the
// following struct.
////////////////////////////////////////////////////////////////////////////
struct RevFlowDepParams {
uuid rev_uuid_;
IpAddress sip_;
RevFlowDepParams() : rev_uuid_(), sip_() {
}
RevFlowDepParams(const uuid &uuid, IpAddress sip) : rev_uuid_(uuid),
sip_(sip) {
}
};

////////////////////////////////////////////////////////////////////////////
// Helper class to manage following,
// 1. VM referred by the flow
Expand Down Expand Up @@ -516,11 +533,10 @@ class FlowEntry {
}
static std::string DropReasonStr(uint16_t reason);
std::string KeyString() const;

void SetEventSandeshData(SandeshFlowIndexInfo *info);
void LogFlow(FlowEventLog::Event event, FlowTableKSyncEntry* ksync,
uint32_t flow_handle, uint8_t gen_id);

void RevFlowDepInfo(RevFlowDepParams *params);
private:
friend class FlowTable;
friend class FlowEntryFreeList;
Expand Down
31 changes: 8 additions & 23 deletions src/vnsw/agent/pkt/flow_mgmt.cc
Original file line number Diff line number Diff line change
Expand Up @@ -110,17 +110,12 @@ void FlowMgmtManager::AddEvent(FlowEntry *flow) {
request_queue_.Enqueue(req);
}

void FlowMgmtManager::DeleteEvent(FlowEntry *flow) {
void FlowMgmtManager::DeleteEvent(FlowEntry *flow,
const RevFlowDepParams &params) {
FlowEntryPtr flow_ptr(flow);
boost::shared_ptr<FlowMgmtRequest>
req(new FlowMgmtRequest(FlowMgmtRequest::DELETE_FLOW, flow_ptr));
request_queue_.Enqueue(req);
}

void FlowMgmtManager::FlowIndexUpdateEvent(FlowEntry *flow) {
FlowEntryPtr flow_ptr(flow);
boost::shared_ptr<FlowMgmtRequest>
req(new FlowMgmtRequest(FlowMgmtRequest::UPDATE_FLOW_INDEX, flow_ptr));
req(new FlowMgmtRequest(FlowMgmtRequest::DELETE_FLOW, flow_ptr,
params));
request_queue_.Enqueue(req);
}

Expand Down Expand Up @@ -360,13 +355,7 @@ bool FlowMgmtManager::RequestHandler(boost::shared_ptr<FlowMgmtRequest> req) {

case FlowMgmtRequest::DELETE_FLOW: {
//Handle the Delete request for flow-mgmt
DeleteFlow(req->flow());
break;
}

case FlowMgmtRequest::UPDATE_FLOW_INDEX: {
//Handle Flow index update for flow-mgmt
UpdateFlowIndex(req->flow());
DeleteFlow(req->flow(), req->params());
break;
}

Expand Down Expand Up @@ -532,11 +521,12 @@ void FlowMgmtManager::AddFlow(FlowEntryPtr &flow) {

}

void FlowMgmtManager::DeleteFlow(FlowEntryPtr &flow) {
void FlowMgmtManager::DeleteFlow(FlowEntryPtr &flow,
const RevFlowDepParams &params) {
LogFlow(flow.get(), "DEL");

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

// Delete entries for flow from the tree
FlowEntryInfo *old_info = FindFlowEntryInfo(flow);
Expand All @@ -563,11 +553,6 @@ void FlowMgmtManager::DeleteFlow(FlowEntryPtr &flow) {
DeleteFlowEntryInfo(flow);
}

void FlowMgmtManager::UpdateFlowIndex(FlowEntryPtr &flow) {
//Enqueue Flow Index Update Event request to flow-stats-collector
agent_->flow_stats_manager()->FlowIndexUpdateEvent(flow);
}

void FlowMgmtManager::UpdateFlowStats(FlowEntryPtr &flow, uint32_t bytes,
uint32_t packets, uint32_t oflow_bytes) {
//Enqueue Flow Index Update Event request to flow-stats-collector
Expand Down
6 changes: 2 additions & 4 deletions src/vnsw/agent/pkt/flow_mgmt.h
Original file line number Diff line number Diff line change
Expand Up @@ -1020,8 +1020,7 @@ class FlowMgmtManager {

Agent *agent() const { return agent_; }
void AddEvent(FlowEntry *low);
void DeleteEvent(FlowEntry *flow);
void FlowIndexUpdateEvent(FlowEntry *flow);
void DeleteEvent(FlowEntry *flow, const RevFlowDepParams &params);
void FlowStatsUpdateEvent(FlowEntry *flow, uint32_t bytes, uint32_t packets,
uint32_t oflow_bytes);
void AddEvent(const DBEntry *entry, uint32_t gen_id);
Expand Down Expand Up @@ -1053,8 +1052,7 @@ class FlowMgmtManager {
// Handle Add/Change of a flow. Builds FlowMgmtKeyTree for all objects
void AddFlow(FlowEntryPtr &flow);
// Handle Delete of a flow. Updates FlowMgmtKeyTree for all objects
void DeleteFlow(FlowEntryPtr &flow);
void UpdateFlowIndex(FlowEntryPtr &flow);
void DeleteFlow(FlowEntryPtr &flow, const RevFlowDepParams &p);
void UpdateFlowStats(FlowEntryPtr &flow, uint32_t bytes, uint32_t packets,
uint32_t oflow_bytes);

Expand Down
17 changes: 12 additions & 5 deletions src/vnsw/agent/pkt/flow_mgmt_request.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ class FlowMgmtRequest {
CHANGE_DBENTRY,
DELETE_DBENTRY,
RETRY_DELETE_VRF,
UPDATE_FLOW_INDEX,
DELETE_BGP_AAS_FLOWS,
UPDATE_FLOW_STATS,
DUMMY
Expand All @@ -29,22 +28,28 @@ class FlowMgmtRequest {

FlowMgmtRequest(Event event, FlowEntryPtr &flow) :
event_(event), flow_(flow), db_entry_(NULL), vrf_id_(0), gen_id_(),
bytes_(), packets_(), oflow_bytes_() {
bytes_(), packets_(), oflow_bytes_(), params_() {
if (event == RETRY_DELETE_VRF)
assert(vrf_id_);
}

FlowMgmtRequest(Event event, FlowEntryPtr &flow,
const RevFlowDepParams &params) :
event_(event), flow_(flow), db_entry_(NULL), vrf_id_(0), gen_id_(),
bytes_(), packets_(), oflow_bytes_(), params_(params) {
}

FlowMgmtRequest(Event event, FlowEntryPtr &flow, uint32_t bytes,
uint32_t packets, uint32_t oflow_bytes) :
event_(event), flow_(flow), db_entry_(NULL), vrf_id_(0), gen_id_(),
bytes_(bytes), packets_(packets), oflow_bytes_(oflow_bytes) {
bytes_(bytes), packets_(packets), oflow_bytes_(oflow_bytes), params_() {
if (event == RETRY_DELETE_VRF)
assert(vrf_id_);
}

FlowMgmtRequest(Event event, const DBEntry *db_entry, uint32_t gen_id) :
event_(event), flow_(NULL), db_entry_(db_entry), vrf_id_(0),
gen_id_(gen_id), bytes_(), packets_(), oflow_bytes_() {
gen_id_(gen_id), bytes_(), packets_(), oflow_bytes_(), params_() {
if (event == RETRY_DELETE_VRF) {
const VrfEntry *vrf = dynamic_cast<const VrfEntry *>(db_entry);
assert(vrf);
Expand All @@ -54,7 +59,7 @@ class FlowMgmtRequest {

FlowMgmtRequest(Event event) :
event_(event), flow_(NULL), db_entry_(NULL), vrf_id_(),
gen_id_(), bytes_(), packets_(), oflow_bytes_() {
gen_id_(), bytes_(), packets_(), oflow_bytes_(), params_() {
}

virtual ~FlowMgmtRequest() { }
Expand Down Expand Up @@ -102,6 +107,7 @@ class FlowMgmtRequest {
uint32_t bytes() const { return bytes_;}
uint32_t packets() const { return packets_;}
uint32_t oflow_bytes() const { return oflow_bytes_;}
const RevFlowDepParams& params() const { return params_; }

private:
Event event_;
Expand All @@ -115,6 +121,7 @@ class FlowMgmtRequest {
uint32_t bytes_;
uint32_t packets_;
uint32_t oflow_bytes_;
RevFlowDepParams params_;

DISALLOW_COPY_AND_ASSIGN(FlowMgmtRequest);
};
Expand Down
45 changes: 19 additions & 26 deletions src/vnsw/agent/pkt/flow_table.cc
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,6 @@ const uint32_t FlowEntryFreeList::kMinThreshold;

SandeshTraceBufferPtr FlowTraceBuf(SandeshTraceBufferCreate("Flow", 5000));

#define FLOW_LOCK(flow, rflow) \
tbb::mutex tmp_mutex1, tmp_mutex2, *mutex_ptr_1, *mutex_ptr_2; \
GetMutexSeq(flow ? flow->mutex() : tmp_mutex1, \
rflow ? rflow->mutex() : tmp_mutex2, \
&mutex_ptr_1, &mutex_ptr_2); \
tbb::mutex::scoped_lock lock1(*mutex_ptr_1); \
tbb::mutex::scoped_lock lock2(*mutex_ptr_2);

/////////////////////////////////////////////////////////////////////////////
// FlowTable constructor/destructor
/////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -138,7 +130,9 @@ FlowEntry *FlowTable::Find(const FlowKey &key) {
}

void FlowTable::Copy(FlowEntry *lhs, FlowEntry *rhs, bool update) {
DeleteFlowInfo(lhs);
RevFlowDepParams params;
lhs->RevFlowDepInfo(&params);
DeleteFlowInfo(lhs, params);
if (rhs)
lhs->Copy(rhs, update);
}
Expand Down Expand Up @@ -277,7 +271,8 @@ void FlowTable::AddInternal(FlowEntry *flow_req, FlowEntry *flow,
AddFlowInfo(flow);
}

void FlowTable::DeleteInternal(FlowEntry *fe, uint64_t time) {
void FlowTable::DeleteInternal(FlowEntry *fe, uint64_t time,
const RevFlowDepParams &params) {
if (fe->deleted()) {
/* Already deleted return from here. */
return;
Expand All @@ -291,7 +286,7 @@ void FlowTable::DeleteInternal(FlowEntry *fe, uint64_t time) {
}
fe->set_reverse_flow_entry(NULL);

DeleteFlowInfo(fe);
DeleteFlowInfo(fe, params);
DeleteKSync(fe);

agent_->stats()->incr_flow_aged();
Expand All @@ -300,13 +295,22 @@ void FlowTable::DeleteInternal(FlowEntry *fe, uint64_t time) {

bool FlowTable::DeleteFlows(FlowEntry *flow, FlowEntry *rflow) {
uint64_t time = UTCTimestampUsec();

/* Fetch reverse-flow info for both flows before their reverse-flow
* links are broken. This info is required during FlowExport */
RevFlowDepParams r_params;
if (rflow) {
rflow->RevFlowDepInfo(&r_params);
}
if (flow) {
RevFlowDepParams f_params;
flow->RevFlowDepInfo(&f_params);
/* Delete the forward flow */
DeleteInternal(flow, time);
DeleteInternal(flow, time, f_params);
}

if (rflow) {
DeleteInternal(rflow, time);
DeleteInternal(rflow, time, r_params);
}
return true;
}
Expand Down Expand Up @@ -497,8 +501,8 @@ void FlowTable::AddFlowInfo(FlowEntry *fe) {
agent_->pkt()->flow_mgmt_manager()->AddEvent(fe);
}

void FlowTable::DeleteFlowInfo(FlowEntry *fe) {
agent_->pkt()->flow_mgmt_manager()->DeleteEvent(fe);
void FlowTable::DeleteFlowInfo(FlowEntry *fe, const RevFlowDepParams &params) {
agent_->pkt()->flow_mgmt_manager()->DeleteEvent(fe, params);
}

/////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -768,12 +772,10 @@ void FlowTable::RevaluateFlow(FlowEntry *flow) {
// must be deleted
void FlowTable::DeleteMessage(FlowEntry *flow) {
DeleteUnLocked(true, flow, flow->reverse_flow_entry());
DeleteFlowInfo(flow);
}

void FlowTable::EvictFlow(FlowEntry *flow, FlowEntry *reverse_flow) {
DeleteUnLocked(false, flow, NULL);
DeleteFlowInfo(flow);

// Reverse flow unlinked with forward flow. Make it short-flow
if (reverse_flow && reverse_flow->deleted() == false) {
Expand Down Expand Up @@ -876,15 +878,6 @@ void FlowTable::UpdateKSync(FlowEntry *flow, bool update) {
mgr->Update(flow);
}

void FlowTable::NotifyFlowStatsCollector(FlowEntry *fe) {
/* FlowMgmt Task does not do anything apart from notifying
* FlowStatsCollector on Flow Index change. We don't directly enqueue
* the index change event to FlowStatsCollector to avoid Flow Index change
* event reaching FlowStatsCollector before Flow Add
*/
agent_->pkt()->flow_mgmt_manager()->FlowIndexUpdateEvent(fe);
}

/////////////////////////////////////////////////////////////////////////////
// Link local flow information tree
/////////////////////////////////////////////////////////////////////////////
Expand Down

0 comments on commit ee2c099

Please sign in to comment.