From e228d3c7e5423ee5885e23dea3dd7a61b21621ed Mon Sep 17 00:00:00 2001 From: ashoksingh Date: Mon, 22 Jun 2015 17:06:47 +0530 Subject: [PATCH] Fix issue of VN reference not being removed from InterfaceUveTable::UveInterfaceState InterfaceUveTable::UveInterfaceState has floating_ip_list which has reference to VN. If interface delete from Nova has not come and config delete for that interface comes (which includes removal of floating IPs), we were not cleaning the floating_ip_list from InterfaceUveTable::UveInterfaceState. Closes-Bug: #1466176 (cherry picked from commit 4aba5649de8c636ea9518443c188664bfe0ab852) Change-Id: I0220edeecb4ad1f65c5b8e58a474f7b9e6888ecc --- src/vnsw/agent/uve/interface_uve_table.cc | 7 ++- .../uve/test/interface_uve_table_test.cc | 10 ++++ .../agent/uve/test/interface_uve_table_test.h | 2 + src/vnsw/agent/uve/test/test_interface_uve.cc | 49 +++++++++++++++++++ 4 files changed, 66 insertions(+), 2 deletions(-) diff --git a/src/vnsw/agent/uve/interface_uve_table.cc b/src/vnsw/agent/uve/interface_uve_table.cc index 872b71f9e8b..06146b1cd32 100644 --- a/src/vnsw/agent/uve/interface_uve_table.cc +++ b/src/vnsw/agent/uve/interface_uve_table.cc @@ -274,7 +274,7 @@ void InterfaceUveTable::InterfaceNotify(DBTablePartBase *partition, delete state; } else { VmInterface::FloatingIpSet old_list; - if (vm_port->cfg_name().empty()) { + if (!state && vm_port->cfg_name().empty()) { /* Skip Add/change notifications if the config_name is empty */ return; } @@ -289,8 +289,11 @@ void InterfaceUveTable::InterfaceNotify(DBTablePartBase *partition, if (state->cfg_name_ != vm_port->cfg_name()) { InterfaceDeleteHandler(state->cfg_name_); state->cfg_name_ = vm_port->cfg_name(); + old_list.clear(); + } + if (!vm_port->cfg_name().empty()) { + InterfaceAddHandler(vm_port, old_list); } - InterfaceAddHandler(vm_port, old_list); } } diff --git a/src/vnsw/agent/uve/test/interface_uve_table_test.cc b/src/vnsw/agent/uve/test/interface_uve_table_test.cc index d5310b1c19a..98f8d83ee25 100644 --- a/src/vnsw/agent/uve/test/interface_uve_table_test.cc +++ b/src/vnsw/agent/uve/test/interface_uve_table_test.cc @@ -71,3 +71,13 @@ const InterfaceUveTable::FloatingIp *InterfaceUveTableTest::GetVmIntfFip } return NULL; } + +InterfaceUveTable::UveInterfaceEntry* +InterfaceUveTableTest::GetUveInterfaceEntry(const string &name) { + InterfaceMap::iterator it = interface_tree_.find(name); + if (it == interface_tree_.end()) { + return NULL; + } + InterfaceUveTable::UveInterfaceEntry* entry = it->second.get(); + return entry; +} diff --git a/src/vnsw/agent/uve/test/interface_uve_table_test.h b/src/vnsw/agent/uve/test/interface_uve_table_test.h index 768cfb47d23..44d059ed551 100644 --- a/src/vnsw/agent/uve/test/interface_uve_table_test.h +++ b/src/vnsw/agent/uve/test/interface_uve_table_test.h @@ -21,6 +21,8 @@ class InterfaceUveTableTest : public InterfaceUveStatsTable { const InterfaceUveTable::FloatingIp *GetVmIntfFip(const VmInterface* intf, const string &fip, const string &vn); const UveVMInterfaceAgent &last_sent_uve() const { return uve_; } + InterfaceUveTable::UveInterfaceEntry* GetUveInterfaceEntry + (const std::string &name); private: uint32_t send_count_; uint32_t delete_count_; diff --git a/src/vnsw/agent/uve/test/test_interface_uve.cc b/src/vnsw/agent/uve/test/test_interface_uve.cc index 7b61b29982d..ac00b4cbd4e 100644 --- a/src/vnsw/agent/uve/test/test_interface_uve.cc +++ b/src/vnsw/agent/uve/test/test_interface_uve.cc @@ -484,6 +484,55 @@ TEST_F(InterfaceUveTest, VmIntfAddDel_2) { vmut->ClearCount(); } +TEST_F(InterfaceUveTest, VmIntfAddDel_3) { + struct PortInfo input[] = { + {"vnet1", 1, "1.1.1.1", "00:00:00:01:01:01", 1, 1}, + }; + + InterfaceUveTableTest *vmut = static_cast + (Agent::GetInstance()->uve()->interface_uve_table()); + vmut->ClearCount(); + EXPECT_EQ(0U, vmut->InterfaceUveCount()); + + // Nova Port add message + util_.NovaPortAdd(input); + + //Verify that entry for interface is not added to our tree until config is + //received. + EXPECT_EQ(0U, vmut->InterfaceUveCount()); + + // Config Port add + util_.ConfigPortAdd(input); + client->WaitForIdle(); + + //Verify that entry for interface is added to our tree after config is + //received. + WAIT_FOR(1000, 500, ((vmut->InterfaceUveCount() == 1U))); + EXPECT_EQ(1U, vmut->InterfaceUveCount()); + + // Config Port delete + DelNode("virtual-machine-interface", "vnet1"); + client->WaitForIdle(); + + //Verify that on deletion of interface config, the entry is marked for + //delete in our tree. + InterfaceUveTable::UveInterfaceEntry* entry = vmut->GetUveInterfaceEntry + ("vnet1"); + EXPECT_TRUE(entry->deleted_); + + // Nova port delete + IntfCfgDel(input, 0); + client->WaitForIdle(); + + util_.EnqueueSendVmiUveTask(); + client->WaitForIdle(); + WAIT_FOR(1000, 500, ((vmut->InterfaceUveCount() == 0U))); + + //clear counters at the end of test case + client->Reset(); + vmut->ClearCount(); +} + TEST_F(InterfaceUveTest, FipStats_1) { InterfaceUveTableTest *vmut = static_cast (Agent::GetInstance()->uve()->interface_uve_table());