Skip to content

Commit

Permalink
* Handle route add messages on delete marked route ksync object
Browse files Browse the repository at this point in the history
If route ksync object is marked for deletion and its empty, then
request to deleted ksync object is enqueued. In the mean time
if any route add messages comes they should be ignored,
handling the same.
Closes-bug:#1582534

Change-Id: I5b102633fdb472f9220dfcb4e50ed35475fbd35c
  • Loading branch information
naveen-n committed May 20, 2016
1 parent d461a26 commit a6adb73
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 4 deletions.
4 changes: 3 additions & 1 deletion src/ksync/ksync_object.cc
Expand Up @@ -1517,7 +1517,9 @@ void KSyncObject::BackRefReEval(KSyncEntry *key) {
bool KSyncObjectManager::Process(KSyncObjectEvent *event) {
switch(event->event_) {
case KSyncObjectEvent::UNREGISTER:
delete event->obj_;
if (event->obj_->Size() == 0) {
delete event->obj_;
}
break;
case KSyncObjectEvent::DELETE:
{
Expand Down
4 changes: 2 additions & 2 deletions src/vnsw/agent/oper/agent_route.cc
Expand Up @@ -351,8 +351,8 @@ void AgentRouteTable::Input(DBTablePartition *part, DBClient *client,
}

if (req->oper == DBRequest::DB_ENTRY_ADD_CHANGE) {
// Ignore ADD_CHANGE if received on deleted VRF
if(vrf->IsDeleted()) {
if (vrf->IsDeleted() &&
vrf->allow_route_add_on_deleted_vrf() == false) {
return;
}

Expand Down
2 changes: 1 addition & 1 deletion src/vnsw/agent/oper/vrf.cc
Expand Up @@ -63,7 +63,7 @@ VrfEntry::VrfEntry(const string &name, uint32_t flags, Agent *agent) :
table_label_(MplsTable::kInvalidLabel),
vxlan_id_(VxLanTable::kInvalidvxlan_id),
rt_table_delete_bmap_(0),
route_resync_walker_(NULL) {
route_resync_walker_(NULL), allow_route_add_on_deleted_vrf_(false) {
}

VrfEntry::~VrfEntry() {
Expand Down
9 changes: 9 additions & 0 deletions src/vnsw/agent/oper/vrf.h
Expand Up @@ -121,6 +121,14 @@ class VrfEntry : AgentRefCount<VrfEntry>, public AgentOperDBEntry {
void SetRouteTableDeleted(uint8_t table_type);
void DeleteRouteTables();
void ResyncRoutes();
bool allow_route_add_on_deleted_vrf() const {
return allow_route_add_on_deleted_vrf_;
}

//To be set in test cases only
void set_allow_route_add_on_deleted_vrf(bool val) {
allow_route_add_on_deleted_vrf_ = val;
}

private:
friend class VrfTable;
Expand All @@ -140,6 +148,7 @@ class VrfEntry : AgentRefCount<VrfEntry>, public AgentOperDBEntry {
uint32_t rt_table_delete_bmap_;
IFMapDependencyManager::IFMapNodePtr vrf_node_ptr_;
boost::scoped_ptr<AgentRouteResync> route_resync_walker_;
bool allow_route_add_on_deleted_vrf_;
DISALLOW_COPY_AND_ASSIGN(VrfEntry);
};

Expand Down
34 changes: 34 additions & 0 deletions src/vnsw/agent/test/test_vrf.cc
Expand Up @@ -59,6 +59,7 @@ class VrfTest : public ::testing::Test {
};

virtual void SetUp() {
agent = Agent::GetInstance();
Agent::GetInstance()->controller()->Cleanup();
client->WaitForIdle();
Agent::GetInstance()->controller()->DisConnect();
Expand Down Expand Up @@ -100,6 +101,7 @@ class VrfTest : public ::testing::Test {
EventManager evm_;
ServerThread *thread_;
test::ControlNodeMock *bgp_peer1;
Agent *agent;
};

//Add VRF1 and fabric VRF
Expand Down Expand Up @@ -371,6 +373,38 @@ TEST_F(VrfTest, DelReqonDeletedVrfRouteTable) {
vrf_ref = NULL;
}

//Test case for bug #1580733
//If route ADD is notified to ksync after route ksync object
//is notified, ksyncobject would unregister from table before
//all the states are cleared
TEST_F(VrfTest, AddReqonDeletedVrfRouteTable) {
client->Reset();
VrfAddReq("vrf1");
EXPECT_TRUE(client->VrfNotifyWait(1));
client->WaitForIdle();

// take reference of vrf entry
VrfEntryRef vrf_ref = VrfGet("vrf1");

vrf_ref->set_allow_route_add_on_deleted_vrf(true);

VrfDelReq("vrf1");
Ip4Address vip(0);
Ip4Address server_ip(0);
Inet4TunnelRouteAdd(agent->local_peer(), "vrf1", vip, 32,
server_ip, TunnelType::AllType(),
16, "vn1", SecurityGroupList(), PathPreference());
client->WaitForIdle();
agent->fabric_inet4_unicast_table()->DeleteReq(agent->local_peer(), "vrf1",
vip, 32, NULL);
client->WaitForIdle();

// release the VRF reference
vrf_ref = NULL;
client->WaitForIdle();
EXPECT_TRUE(VrfFind("vrf1", true) == false);
}

int main(int argc, char **argv) {
GETUSERARGS();
client = TestInit(init_file, ksync_init, false, true, false);
Expand Down
12 changes: 12 additions & 0 deletions src/vnsw/agent/vrouter/ksync/route_ksync.cc
Expand Up @@ -724,6 +724,18 @@ RouteKSyncObject::~RouteKSyncObject() {
table_delete_ref_.Reset(NULL);
}

KSyncDBObject::DBFilterResp
RouteKSyncObject::DBEntryFilter(const DBEntry *entry,
const KSyncDBEntry *ksync) {
const AgentRoute *route = static_cast<const AgentRoute *>(entry);
// Ignore Add/Change notifications when VRF is deleted
if (route->vrf()->IsDeleted() == true) {
return DBFilterIgnore;
}

return DBFilterAccept;
}

KSyncEntry *RouteKSyncObject::Alloc(const KSyncEntry *entry, uint32_t index) {
const RouteKSyncEntry *route = static_cast<const RouteKSyncEntry *>(entry);
RouteKSyncEntry *ksync = new RouteKSyncEntry(this, route, index);
Expand Down
1 change: 1 addition & 0 deletions src/vnsw/agent/vrouter/ksync/route_ksync.h
Expand Up @@ -109,6 +109,7 @@ class RouteKSyncObject : public KSyncDBObject {
void ManagedDelete();
void Unregister();
virtual void EmptyTable();
DBFilterResp DBEntryFilter(const DBEntry *entry, const KSyncDBEntry *ksync);

private:
KSync *ksync_;
Expand Down

0 comments on commit a6adb73

Please sign in to comment.