Skip to content

Commit

Permalink
Merge "Set db_entry in RouteFlowMgmtKey on delete-operation"
Browse files Browse the repository at this point in the history
  • Loading branch information
Zuul authored and opencontrail-ci-admin committed Nov 28, 2015
2 parents 31e945f + f9c33e8 commit b635a7c
Show file tree
Hide file tree
Showing 4 changed files with 198 additions and 4 deletions.
24 changes: 20 additions & 4 deletions src/vnsw/agent/pkt/flow_mgmt.cc
Expand Up @@ -1077,8 +1077,26 @@ bool RouteFlowMgmtTree::Delete(FlowMgmtKey *key, FlowEntry *flow) {
return ret;
}

void RouteFlowMgmtTree::SetDBEntry(const FlowMgmtRequest *req,
FlowMgmtKey *key) {
Tree::iterator it = tree_.find(key);
if (it == tree_.end()) {
return;
}

if (it->first->db_entry()) {
assert(it->first->db_entry() == req->db_entry());
return;
}
it->first->set_db_entry(req->db_entry());
return;
}

bool RouteFlowMgmtTree::OperEntryDelete(const FlowMgmtRequest *req,
FlowMgmtKey *key) {
// Set the db_entry if it was not set earlier. It is needed to send the
// FreeDBState message
SetDBEntry(req, key);
bool ret = FlowMgmtTree::OperEntryDelete(req, key);
RouteFlowMgmtKey *route_key = static_cast<RouteFlowMgmtKey *>(key);
mgr_->RetryVrfDelete(route_key->vrf_id());
Expand All @@ -1091,10 +1109,8 @@ bool RouteFlowMgmtTree::OperEntryAdd(const FlowMgmtRequest *req,
if (req->db_entry() == NULL)
return ret;

Tree::iterator it = tree_.find(key);
if (it != tree_.end()) {
it->first->set_db_entry(req->db_entry());
}
// Set the DBEntry in the flow-mgmt-entry
SetDBEntry(req, key);
return ret;
}

Expand Down
1 change: 1 addition & 0 deletions src/vnsw/agent/pkt/flow_mgmt.h
Expand Up @@ -640,6 +640,7 @@ class RouteFlowMgmtTree : public FlowMgmtTree {
virtual bool OperEntryDelete(const FlowMgmtRequest *req, FlowMgmtKey *key);
virtual bool OperEntryAdd(const FlowMgmtRequest *req, FlowMgmtKey *key);
private:
void SetDBEntry(const FlowMgmtRequest *req, FlowMgmtKey *key);
DISALLOW_COPY_AND_ASSIGN(RouteFlowMgmtTree);
};

Expand Down
2 changes: 2 additions & 0 deletions src/vnsw/agent/pkt/test/SConscript
Expand Up @@ -19,6 +19,8 @@ env.Prepend(LIBS = 'agent_physical_devices_test_xml')
pkt_test_suite = []
pkt_flaky_test_suite = []

test_flow_mgmt_route = AgentEnv.MakeTestCmd(env, 'test_flow_mgmt_route',
pkt_test_suite)
test_pkt = AgentEnv.MakeTestCmd(env, 'test_pkt', pkt_flaky_test_suite)
test_pkt_flow_mock = AgentEnv.MakeTestCmd(env, 'test_pkt_flow_mock',
pkt_flaky_test_suite)
Expand Down
175 changes: 175 additions & 0 deletions src/vnsw/agent/pkt/test/test_flow_mgmt_route.cc
@@ -0,0 +1,175 @@
/*
* Copyright (c) 2015 Juniper Networks, Inc. All rights reserved.
*/

#include "base/os.h"
#include "test/test_cmn_util.h"
#include "test_flow_util.h"
#include "ksync/ksync_sock_user.h"
#include "oper/tunnel_nh.h"
#include "pkt/flow_mgmt.h"
#include <algorithm>

#define vm1_ip "1.1.1.1"
#define vm2_ip "1.1.1.2"

struct PortInfo input[] = {
{"vif0", 1, vm1_ip, "00:00:00:01:01:01", 1, 1},
{"vif1", 2, vm2_ip, "00:00:00:01:01:02", 1, 2},
};

class FlowMgmtRouteTest : public ::testing::Test {
public:
FlowMgmtRouteTest() : peer_(NULL), agent_(Agent::GetInstance()) {
flow_proto_ = agent_->pkt()->get_flow_proto();
flow_mgmt_ = agent_->pkt()->flow_mgmt_manager();
eth = EthInterfaceGet("vnet0");
EXPECT_TRUE(eth != NULL);
}

void FlushFlowTable() {
client->EnqueueFlowFlush();
client->WaitForIdle();
WAIT_FOR(100, 100, (flow_proto_->FlowCount() == 0));
}

protected:
virtual void SetUp() {
WAIT_FOR(100, 100, (flow_proto_->FlowCount() == 0));
client->Reset();

CreateVmportEnv(input, 2, 1);
client->WaitForIdle(5);

EXPECT_TRUE(VmPortActive(input, 0));
EXPECT_TRUE(VmPortActive(input, 1));

vif0 = VmInterfaceGet(input[0].intf_id);
assert(vif0);
vif1 = VmInterfaceGet(input[1].intf_id);
assert(vif1);

client->WaitForIdle();
peer_ = CreateBgpPeer(Ip4Address(1), "BGP Peer 1");

client->WaitForIdle();
}

virtual void TearDown() {
FlushFlowTable();
client->Reset();

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

EXPECT_FALSE(VmPortFind(input, 0));
EXPECT_FALSE(VmPortFind(input, 1));

EXPECT_EQ(0U, agent()->vm_table()->Size());
EXPECT_EQ(0U, agent()->vn_table()->Size());
EXPECT_EQ(0U, agent()->acl_table()->Size());
DeleteBgpPeer(peer_);
}

Agent *agent() {return agent_;}

protected:
BgpPeer *peer_;
Agent *agent_;
FlowProto *flow_proto_;
FlowMgmtManager *flow_mgmt_;
VmInterface *vif0;
VmInterface *vif1;
PhysicalInterface *eth;
};

TEST_F(FlowMgmtRouteTest, RouteDelete_1) {
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);

InetUnicastRouteKey key(peer_, vrf_name, remote_subnet, 24);
InetUnicastAgentRouteTable *table =
vif0->vrf()->GetInet4UnicastRouteTable();
AgentRoute *rt = table->FindRoute(remote_ip);

flow_mgmt_->DeleteEvent(rt, 0xFFFFFFFF);
client->WaitForIdle();

DeleteRoute(vrf_name.c_str(), remote_subnet.to_string().c_str(), 24, peer_);
}

TEST_F(FlowMgmtRouteTest, RouteDelete_2) {
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);

InetUnicastRouteKey key(peer_, vrf_name, remote_subnet, 24);
InetUnicastAgentRouteTable *table =
vif0->vrf()->GetInet4UnicastRouteTable();
AgentRoute *rt = table->FindRoute(remote_ip);

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

flow_mgmt_->DeleteEvent(rt, 0xFFFFFFFF);
client->WaitForIdle();

DeleteRoute(vrf_name.c_str(), remote_subnet.to_string().c_str(), 24, peer_);
}

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

GETUSERARGS();
client = TestInit(init_file, ksync_init, true, true, true, 100*1000);
ret = RUN_ALL_TESTS();
usleep(100000);
TestShutdown();
delete client;
return ret;
}

0 comments on commit b635a7c

Please sign in to comment.