Skip to content

Commit

Permalink
Merge "Skip adding flow into flow management tree when VRF is deleted"
Browse files Browse the repository at this point in the history
  • Loading branch information
Zuul authored and opencontrail-ci-admin committed Dec 5, 2015
2 parents a7af877 + 3036a83 commit a8753f1
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 6 deletions.
19 changes: 13 additions & 6 deletions src/vnsw/agent/pkt/flow_mgmt.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1120,6 +1120,11 @@ bool RouteFlowMgmtTree::OperEntryAdd(const FlowMgmtRequest *req,
void InetRouteFlowMgmtTree::ExtractKeys(FlowEntry *flow, FlowMgmtKeyTree *tree,
uint32_t vrf, const IpAddress &ip,
uint8_t plen) {
// We do not support renewal of VRF, so skip flow if VRF is deleted
if (mgr_->agent()->vrf_table()->FindVrfFromId(vrf) == NULL) {
return;
}

InetRouteFlowMgmtKey *key = NULL;
if (ip.is_v4()) {
Ip4Address ip4 = Address::GetIp4SubnetAddress(ip.to_v4(), plen);
Expand Down Expand Up @@ -1229,16 +1234,18 @@ void BridgeRouteFlowMgmtTree::ExtractKeys(FlowEntry *flow,
if (flow->l3_flow() == true)
return;

if (flow->data().flow_source_vrf != VrfEntry::kInvalidIndex) {
VrfTable *table = mgr_->agent()->vrf_table();
uint32_t vrf = flow->data().flow_source_vrf;
if (vrf != VrfEntry::kInvalidIndex && table->FindVrfFromId(vrf) != NULL) {
BridgeRouteFlowMgmtKey *key =
new BridgeRouteFlowMgmtKey(flow->data().flow_source_vrf,
flow->data().smac);
new BridgeRouteFlowMgmtKey(vrf, flow->data().smac);
AddFlowMgmtKey(tree, key);
}
if (flow->data().flow_dest_vrf != VrfEntry::kInvalidIndex) {

vrf = flow->data().flow_dest_vrf;
if (vrf != VrfEntry::kInvalidIndex && table->FindVrfFromId(vrf) != NULL) {
BridgeRouteFlowMgmtKey *key =
new BridgeRouteFlowMgmtKey(flow->data().flow_dest_vrf,
flow->data().smac);
new BridgeRouteFlowMgmtKey(vrf, flow->data().smac);
AddFlowMgmtKey(tree, key);
}
}
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 @@ -967,6 +967,8 @@ class FlowMgmtManager {
FlowMgmtDbClient *flow_mgmt_dbclient() const {
return flow_mgmt_dbclient_.get();
}

void DisableWorkQueue(bool disable) { request_queue_.set_disable(disable); }
private:
// Handle Add/Change of a flow. Builds FlowMgmtKeyTree for all objects
void AddFlow(FlowEntryPtr &flow);
Expand Down
8 changes: 8 additions & 0 deletions src/vnsw/agent/pkt/flow_proto.cc
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,14 @@ bool FlowProto::Enqueue(boost::shared_ptr<PktInfo> msg) {
return ret;
}

void FlowProto::DisableFlowEventQueue(uint32_t index, bool disabled) {
flow_event_queue_[index]->set_disable(disabled);
}

void FlowProto::DisableFlowMgmtQueue(bool disabled) {
flow_update_queue_.set_disable(disabled);
}

/////////////////////////////////////////////////////////////////////////////
// FlowTable related routines
/////////////////////////////////////////////////////////////////////////////
Expand Down
2 changes: 2 additions & 0 deletions src/vnsw/agent/pkt/flow_proto.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ class FlowProto : public Proto {
void CreateAuditEntry(FlowEntry *flow);
bool FlowEventHandler(const FlowEvent &req);

void DisableFlowEventQueue(uint32_t index, bool disabled);
void DisableFlowMgmtQueue(bool disabled);
private:
std::vector<FlowEventQueue *> flow_event_queue_;
std::vector<FlowTable *> flow_table_list_;
Expand Down
84 changes: 84 additions & 0 deletions src/vnsw/agent/pkt/test/test_flow_mgmt_route.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* Copyright (c) 2015 Juniper Networks, Inc. All rights reserved.
*/

#include <netinet/in.h>
#include "base/os.h"
#include "test/test_cmn_util.h"
#include "test_flow_util.h"
Expand Down Expand Up @@ -162,6 +163,89 @@ TEST_F(FlowMgmtRouteTest, RouteDelete_2) {
DeleteRoute(vrf_name.c_str(), remote_subnet.to_string().c_str(), 24, peer_);
}

TEST_F(FlowMgmtRouteTest, RouteDelete_3) {
EXPECT_EQ(0U, flow_proto_->FlowCount());

boost::system::error_code ec;
Ip4Address remote_subnet = Ip4Address::from_string("10.10.10.0", ec);
Ip4Address remote_ip = Ip4Address::from_string("10.10.10.1", ec);
Ip4Address remote_compute = Ip4Address::from_string("1.1.1.1", ec);

string vrf_name = vif0->vrf()->GetName();
string vn_name = vif0->vn()->GetName();
Inet4TunnelRouteAdd(peer_, vrf_name, remote_subnet, 24, remote_compute,
TunnelType::AllType(), 10, vn_name, SecurityGroupList(),
PathPreference());
client->WaitForIdle();

char router_id[80];
strcpy(router_id, Agent::GetInstance()->router_id().to_string().c_str());
TxIpMplsPacket(eth->id(), remote_compute.to_string().c_str(),
router_id, vif0->label(), remote_ip.to_string().c_str(),
vm1_ip, 1, 1);
client->WaitForIdle();

uint32_t vrf_id = vif0->vrf_id();
FlowEntry *flow = FlowGet(vrf_id, remote_ip.to_string().c_str(),
vm1_ip, 1, 0, 0, vif0->flow_key_nh()->id());
EXPECT_TRUE(flow != NULL);

flow_mgmt_->DeleteEvent(flow);
client->WaitForIdle();

DeleteRoute(vrf_name.c_str(), remote_subnet.to_string().c_str(), 24, peer_);
client->WaitForIdle();
}

TEST_F(FlowMgmtRouteTest, RouteDelete_4) {
EXPECT_EQ(0U, flow_proto_->FlowCount());

boost::system::error_code ec;
Ip4Address remote_subnet = Ip4Address::from_string("10.10.10.0", ec);
Ip4Address remote_ip = Ip4Address::from_string("10.10.10.1", ec);
Ip4Address remote_compute = Ip4Address::from_string("1.1.1.1", ec);
char router_id[80];
strcpy(router_id, Agent::GetInstance()->router_id().to_string().c_str());

string vrf_name = vif0->vrf()->GetName();
string vn_name = vif0->vn()->GetName();
Inet4TunnelRouteAdd(peer_, vrf_name, remote_subnet, 24, remote_compute,
TunnelType::AllType(), 10, vn_name, SecurityGroupList(),
PathPreference());
client->WaitForIdle();

TxIpMplsPacket(eth->id(), remote_compute.to_string().c_str(),
router_id, vif0->label(), remote_ip.to_string().c_str(),
vm1_ip, 1, 1);
client->WaitForIdle();
FlowEntry *flow = FlowGet(vif0->vrf_id(), remote_ip.to_string().c_str(),
vm1_ip, 1, 0, 0, vif0->flow_key_nh()->id());
EXPECT_TRUE(flow != NULL);

FlowMgmtManager *mgr = agent_->pkt()->flow_mgmt_manager();
flow_proto_->DisableFlowEventQueue(0, true);

VrfDelReq("vrf1");
client->WaitForIdle(10);

flow_proto_->DisableFlowMgmtQueue(true);
flow_mgmt_->DeleteEvent(flow);
flow_mgmt_->DeleteEvent(flow->reverse_flow_entry());
flow_mgmt_->AddEvent(flow);
flow_mgmt_->AddEvent(flow->reverse_flow_entry());
client->WaitForIdle();

DeleteVmportEnv(input, 3, true, 1);
client->WaitForIdle(3);

flow_proto_->DisableFlowMgmtQueue(false);
mgr->DisableWorkQueue(false);
client->WaitForIdle(10);

flow_proto_->DisableFlowEventQueue(0, false);
client->WaitForIdle(10);
}

int main(int argc, char *argv[]) {
int ret = 0;

Expand Down

0 comments on commit a8753f1

Please sign in to comment.