Skip to content

Commit

Permalink
Merge "Agent changes for TCP connection state awareness for faster fl…
Browse files Browse the repository at this point in the history
…ow aging 1> Flow eviction by vrouter If a closed or reset TCP session flow is present in a flow bucket then vrouter could evict the flow and use the slot for a new flow, agent would then delete the evicted flow internally and send a message to delete reverse flow 2> Closes or reset flow would be deleted by agent during aging cycle. 3> If a flow is stuck in SYN state for more than 180 seconds delete the flow. TBD: Update stats for deleted flow Partial-BUG: #1362701" into R2.20
  • Loading branch information
Zuul authored and opencontrail-ci-admin committed Oct 26, 2015
2 parents 821dc30 + d5d1f1a commit 10e61e1
Show file tree
Hide file tree
Showing 12 changed files with 445 additions and 31 deletions.
63 changes: 63 additions & 0 deletions src/vnsw/agent/pkt/flow_table.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1472,6 +1472,7 @@ bool FlowEntry::InitFlowCmn(const PktFlowInfo *info, const PktControlInfo *ctrl,
data_.in_vm_entry = ctrl->vm_ ? ctrl->vm_ : NULL;
data_.out_vm_entry = rev_ctrl->vm_ ? rev_ctrl->vm_ : NULL;
l3_flow_ = info->l3_flow;
data_.vrouter_evicted_flow_ = false;

return true;
}
Expand Down Expand Up @@ -2031,6 +2032,44 @@ RouteFlowInfo *FlowTable::FindRouteFlowInfo(RouteFlowInfo *key) {
return route_flow_tree_.LPMFind(key);
}

void FlowTable::DeleteVrouterEvictedFlow(FlowEntry *flow) {
if (flow->deleted() == false) {
flow->data().vrouter_evicted_flow_ = true;
if (flow->reverse_flow_entry()) {
flow->reverse_flow_entry()->data().vrouter_evicted_flow_ = true;
}
Delete(flow->key(), true);
}
}

void FlowTable::InsertByIndex(uint32_t flow_handle, FlowEntry *flow) {
if (flow_handle != FlowEntry::kInvalidFlowHandle &&
flow->deleted() == false) {
FlowEntry *old_flow = FindByIndex(flow_handle);
if (old_flow == NULL) {
flow_index_tree_.insert(std::pair<uint32_t,FlowEntryPtr>(flow_handle,
flow));
} else if (old_flow != flow) {
assert(0);
}
}
}

void FlowTable::DeleteByIndex(uint32_t flow_handle, FlowEntry *fe) {
if (flow_handle != FlowEntry::kInvalidFlowHandle) {
if (FindByIndex(flow_handle) == fe) {
flow_index_tree_.erase(flow_handle);
}
}
}

FlowEntry* FlowTable::FindByIndex(uint32_t flow_handle) {
FlowIndexTree::iterator it = flow_index_tree_.find(flow_handle);
if (it != flow_index_tree_.end()) {
return it->second.get();
}
return NULL;
}
////////////////////////////////////////////////////////////////////////////
// RouteFlowKey methods
////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -2753,6 +2792,8 @@ void FlowTable::DeleteFlowInfo(FlowEntry *fe)
DeleteVmFlowInfo(fe);
// Remove from RouteFlowTree
DeleteRouteFlowInfo(fe);
//Remove from flow handle tree
DeleteByIndex(fe->flow_handle_, fe);
}

void FlowTable::DeleteVnFlowInfo(FlowEntry *fe)
Expand Down Expand Up @@ -2910,6 +2951,8 @@ void FlowTable::AddFlowInfo(FlowEntry *fe)
AddVmFlowInfo(fe);
// Add RouteFlowTree;
AddRouteFlowInfo(fe);

AddIndexFlowInfo(fe, fe->flow_handle_);
}

void FlowTable::AddAclFlowInfo (FlowEntry *fe)
Expand Down Expand Up @@ -3216,6 +3259,26 @@ void FlowTable::AddRouteFlowInfo (FlowEntry *fe) {
}
}

void FlowTable::AddIndexFlowInfo(FlowEntry *fe, uint32_t flow_handle) {
if (flow_handle == FlowEntry::kInvalidFlowHandle ||
fe->deleted() == true) {
fe->set_flow_handle(flow_handle, this);
return;
}

if (flow_handle != fe->flow_handle_) {
DeleteByIndex(flow_handle, fe);
}

FlowEntry *flow = FindByIndex(flow_handle);
if (flow && flow != fe) {
DeleteVrouterEvictedFlow(flow);
}

InsertByIndex(flow_handle, fe);
fe->set_flow_handle(flow_handle, this);
}

void FlowTable::ResyncAFlow(FlowEntry *fe) {
fe->UpdateRpf();
fe->DoPolicy();
Expand Down
11 changes: 10 additions & 1 deletion src/vnsw/agent/pkt/flow_table.h
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ struct FlowData {
component_nh_idx((uint32_t)CompositeNH::kInvalidComponentNHIdx),
nh_state_(NULL), source_plen(0), dest_plen(0), drop_reason(0),
vrf_assign_evaluated(false), pending_recompute(false), enable_rpf(true),
l2_rpf_plen(Address::kMaxV4PrefixLen) {}
l2_rpf_plen(Address::kMaxV4PrefixLen), vrouter_evicted_flow_(false) {}

MacAddress smac;
MacAddress dmac;
Expand Down Expand Up @@ -260,6 +260,7 @@ struct FlowData {
FlowRouteRefMap flow_dest_plen_map;
bool enable_rpf;
uint8_t l2_rpf_plen;
bool vrouter_evicted_flow_;
};

class FlowEntry {
Expand Down Expand Up @@ -596,6 +597,8 @@ class FlowTable {
typedef std::map<const VmEntry *, VmFlowInfo *> VmFlowTree;
typedef std::pair<const VmEntry *, VmFlowInfo *> VmFlowPair;

typedef std::map<uint32_t, FlowEntryPtr> FlowIndexTree;

typedef Patricia::Tree<RouteFlowInfo, &RouteFlowInfo::node, RouteFlowInfo::KeyCmp> RouteFlowTree;
typedef boost::function<bool(FlowEntry *flow)> FlowEntryCb;

Expand Down Expand Up @@ -715,6 +718,11 @@ class FlowTable {
// Update flow port bucket information
void NewFlow(const FlowEntry *flow);
void DeleteFlow(const FlowEntry *flow);
void DeleteByIndex(uint32_t flow_handle, FlowEntry *flow);
void InsertByIndex(uint32_t flow_handle, FlowEntry *flow);
FlowEntry *FindByIndex(uint32_t flow_handle);
void DeleteVrouterEvictedFlow(FlowEntry *flow);
void AddIndexFlowInfo(FlowEntry *fe, uint32_t flow_index);
friend class FlowStatsCollector;
friend class PktSandeshFlow;
friend class FetchFlowRecord;
Expand Down Expand Up @@ -748,6 +756,7 @@ class FlowTable {

InetUnicastRouteEntry inet4_route_key_;
InetUnicastRouteEntry inet6_route_key_;
FlowIndexTree flow_index_tree_;

// maintain the linklocal flow info against allocated fd, debug purpose only
LinkLocalFlowInfoMap linklocal_flow_info_map_;
Expand Down
66 changes: 66 additions & 0 deletions src/vnsw/agent/pkt/test/tcp_flow.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?xml version="1.0"?>
<test_suite name="pkt-parse">
<test name="vrf-vn-1" verbose="0">
<virtual-network uuid="1" name="vn1" vxlan-id="2" network-id="2"/>
<virtual-machine uuid="1" name="vm1"/>
<vrf uuid="1" name="vrf1" />
<vmi-vrf uuid="1" name="tap1-vm1" />
<link left="virtual-network" left-name="vn1"
right="routing-instance" right-name="vrf1" />

<virtual-machine-interface nova="1"
uuid="1" name="tap1" mac="00:00:00:00:01:01" vn-name="vn1" vn-uuid="1"
vm-name="vm1" vm-uuid="1" vrf="vrf1" ip="1.1.1.1"
/>

<validate name="validate-1">
<virtual-network name="vn1" uuid="1" present="1" />
<virtual-machine-interface name="tap1" uuid="1" present="1" active="1" />
<virtual-machine name="vm1" uuid="1" present="1"/>
</validate>
<fdb uuid="1" id="1" name="fdb_1" mac="00:00:00:00:01:02" vrf="vrf1"
vn="vn1" vxlan_id="0" tunnel-dest="5.5.5.5" tunnel-type="vxlan" sg="2"
label="5" />

<packet uuid="1" id="1" name="l2-tcp-from-fabric" intf="1" fwd_mode="l2"
tunnel_type="vxlan" tunnel_sip="10.10.10.10"
smac="00:00:00:00:01:02" dmac="00:00:00:00:01:01"
sip="1.1.1.2" dip="1.1.1.1" proto="tcp" sport="1" dport="1"
type="flow" hash_id="1"/>

<validate name="validate-1">
<flow name="l2-vxlan-tcp-to-vm-vxlan-1" uuid="1" vrf="vrf1" nh="10" sip="1.1.1.2"
dip="1.1.1.1" proto="tcp" sport="1" dport="1" svn="vn1"
dvn="vn1" action="pass"/>
</validate>


<packet uuid="1" id="1" name="l2-tcp-from-fabric" intf="1" fwd_mode="l2"
tunnel_type="gre" tunnel_sip="10.10.10.10"
smac="00:00:00:00:01:02" dmac="00:00:00:00:01:01"
sip="1.1.1.2" dip="1.1.1.1" proto="tcp" sport="1" dport="2"
type="flow" hash_id="1"/>

<validate name="validate-2">
<flow name="l2-vxlan-tcp-to-vm-vxlan-2" uuid="1" vrf="vrf1" nh="10" sip="1.1.1.2"
dip="1.1.1.1" proto="tcp" sport="1" dport="1" svn="vn1"
dvn="vn1" deleted="true"/>
<flow name="l2-gre-tcp-to-vm-gre-1" uuid="1" vrf="vrf1" nh="14" sip="1.1.1.2"
dip="1.1.1.1" proto="tcp" sport="1" dport="2" svn="vn1"
dvn="vn1" action="pass"/>
</validate>

<fdb uuid="1" id="1" name="fdb_1" delete="1" mac="00:00:00:00:01:02" vrf="vrf1"
vn="vn1" vxlan_id="0" tunnel-dest="5.5.5.5" tunnel-type="vxlan" sg="1"
label="5" />
<virtual-machine-interface delete="1" nova="1"
uuid="1" name="tap1" mac="00:00:00:00:00:01" vn-name="vn1" vn-uuid="1"
vm-name="vm1" vm-uuid="1" vrf="vrf1" ip="1.1.1.1"
/>

<virtual-machine delete="1" uuid="1" name="vm1"/>
<vmi-vrf delete="1" uuid="1" name="tap1-vm1" />
<vrf delete="1" uuid="1" name="vrf1" />
<virtual-network delete="1" uuid="1" name="vn1">
</test>
</test_suite>
20 changes: 20 additions & 0 deletions src/vnsw/agent/pkt/test/test_xml_packet_ut.cc
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,26 @@ TEST_F(TestPkt, unknown_unicast_flood) {
client->agent()->flow_stats_collector()->set_delete_short_flow(false);
}

TEST_F(TestPkt, tcp) {
AgentUtXmlTest test("controller/src/vnsw/agent/pkt/test/tcp_flow.xml");
AgentUtXmlOperInit(&test);
if (test.Load() == true) {
test.ReadXml();

string str;
test.ToString(&str);
cout << str << endl;
test.Run();
}
client->WaitForIdle();
client->agent()->flow_stats_collector()->set_delete_short_flow(true);
client->EnqueueFlowAge();
client->WaitForIdle();
WAIT_FOR(000, 1000, (0U == client->agent()->pkt()->flow_table()->Size()));
client->agent()->flow_stats_collector()->set_delete_short_flow(false);
}


TEST_F(TestPkt, flow_tsn_mode_1) {
Agent *agent = Agent::GetInstance();
//agent->set_tsn_enabled(true);
Expand Down
8 changes: 8 additions & 0 deletions src/vnsw/agent/test-xml/test_xml_oper.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1289,6 +1289,10 @@ bool AgentUtXmlFlowValidate::ReadXml() {
if (GetUintAttribute(node(), "rpf_nh", &rpf_nh_) == false) {
rpf_nh_ = 0;
}

if (GetStringAttribute(node(), "deleted", &deleted_) == false) {
deleted_ = "false";
}
return true;
}

Expand All @@ -1308,6 +1312,10 @@ static bool MatchFlowAction(FlowEntry *flow, const string &str) {
bool AgentUtXmlFlowValidate::Validate() {
FlowEntry *flow = FlowGet(0, sip_, dip_, proto_id_, sport_, dport_,
nh_id_);
if (deleted_ == "true" && flow == NULL) {
return true;
}

if (present() == false)
return (flow == NULL);

Expand Down
1 change: 1 addition & 0 deletions src/vnsw/agent/test-xml/test_xml_oper.h
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,7 @@ class AgentUtXmlFlowValidate : public AgentUtXmlValidationNode {
std::string dvn_;
std::string action_;
uint16_t rpf_nh_;
std::string deleted_;
};

class AgentUtXmlL2Route : public AgentUtXmlNode {
Expand Down
6 changes: 6 additions & 0 deletions src/vnsw/agent/test-xml/test_xml_packet.cc
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ using namespace std;
using namespace pugi;
using namespace boost::uuids;
using namespace AgentUtXmlUtils;
int hash_id = 1;

AgentUtXmlPacketUtils::AgentUtXmlPacketUtils() {
name_ = "pkt";
Expand Down Expand Up @@ -133,6 +134,11 @@ bool AgentUtXmlPacketUtils::ReadXml(const pugi::xml_node &node) {
GetUintAttribute(node, "proto", &proto_id_);
GetUintAttribute(node, "sport", &sport_);
GetUintAttribute(node, "dport", &dport_);
GetUintAttribute(node, "hash_id", (uint16_t *)&hash_id_);

if (hash_id_ == 0) {
hash_id_ = hash_id++;
}
return true;
}

Expand Down

0 comments on commit 10e61e1

Please sign in to comment.