From 5b13a693aa86ae781958ad5eddf6d347ce6b0290 Mon Sep 17 00:00:00 2001 From: Naveen N Date: Tue, 9 Dec 2014 03:17:48 -0800 Subject: [PATCH] * Path preference change was enqueued every time, interface config change and hence, preference would be overwritten, because of this. Removed the code to enqueue explicit path preference change. Instead copy config driven field in local vm add change path. Added test case for same. Closes-bug:#1379481 (cherry picked from commit cfde6909bd93b91851e4cbcfcd507c5f3bd83b9b) Conflicts: src/vnsw/agent/oper/vm_interface.cc Change-Id: Idb9c5eab91ed20c6119d21bae05462bc5c7744c9 --- src/vnsw/agent/oper/agent_path.cc | 13 ++++-- src/vnsw/agent/oper/agent_path.h | 17 +++++++ src/vnsw/agent/oper/test/test_aap.cc | 66 ++++++++++++++++++++++++++++ src/vnsw/agent/oper/vm_interface.cc | 14 ------ 4 files changed, 93 insertions(+), 17 deletions(-) diff --git a/src/vnsw/agent/oper/agent_path.cc b/src/vnsw/agent/oper/agent_path.cc index 361c6134e43..4f269c89608 100644 --- a/src/vnsw/agent/oper/agent_path.cc +++ b/src/vnsw/agent/oper/agent_path.cc @@ -407,9 +407,16 @@ bool LocalVmRoute::AddChangePath(Agent *agent, AgentPath *path) { ret = true; } - //If there is a transition in path from active-active to - //ative-backup or vice-versa copy over entire path preference structure - if (path->path_preference().ecmp() != path_preference_.ecmp()) { + //Priority and sequence no of path are updated from path + //preference state machine + //Path preference value enqueued here would be copied + //only if + //1> ecmp field is set to true, meaning path would be + // active-active + //2> static preference is set, meaning external entity + // would specify the preference of this path(ex LBaaS) + //3> Change in priority when static preference is set + if (path->path_preference().ConfigChanged(path_preference_)) { path->set_path_preference(path_preference_); ret = true; } diff --git a/src/vnsw/agent/oper/agent_path.h b/src/vnsw/agent/oper/agent_path.h index 2950729dc8c..0f63e08abd2 100644 --- a/src/vnsw/agent/oper/agent_path.h +++ b/src/vnsw/agent/oper/agent_path.h @@ -75,6 +75,23 @@ class PathPreference { } return false; } + + //Check if any configuration values have changed + //ecmp flag and static preference are updated from + //configuration, if static preference flag is set, + //then preference also would be picked from configuration + bool ConfigChanged(PathPreference &rhs) const { + bool ret = false; + if (ecmp_ != rhs.ecmp_) { + ret = true; + } else if (static_preference_ != rhs.static_preference_) { + ret = true; + } else if (static_preference_ && preference_ != rhs.preference_) { + ret = true; + } + return ret; + } + private: uint32_t sequence_; Preference preference_; diff --git a/src/vnsw/agent/oper/test/test_aap.cc b/src/vnsw/agent/oper/test/test_aap.cc index aaee0922562..d212beb01e5 100644 --- a/src/vnsw/agent/oper/test/test_aap.cc +++ b/src/vnsw/agent/oper/test/test_aap.cc @@ -88,6 +88,21 @@ class TestAap : public ::testing::Test { client->WaitForIdle(); } + void AddStaticPreference(std::string intf_name, int intf_id, + uint32_t value) { + std::ostringstream buf; + buf << ""; + buf << ""; + buf << value; + buf << ""; + buf << ""; + char cbuf[10000]; + strcpy(cbuf, buf.str().c_str()); + AddNode("virtual-machine-interface", intf_name.c_str(), + intf_id, cbuf); + client->WaitForIdle(); + } + virtual void SetUp() { CreateVmportEnv(input, 1); client->WaitForIdle(); @@ -471,6 +486,57 @@ TEST_F(TestAap, StateMachine_9) { EXPECT_TRUE(path->path_preference().wait_for_traffic() == false); } +//Verify that static preference is populated +TEST_F(TestAap, StateMachine_10) { + AddStaticPreference("intf1", 1, 200); + Ip4Address ip = Ip4Address::from_string("1.1.1.1"); + EXPECT_TRUE(RouteFind("vrf1", ip, 32)); + + VmInterface *vm_intf = VmInterfaceGet(1); + Inet4UnicastRouteEntry *rt = + RouteGet("vrf1", ip, 32); + const AgentPath *path = rt->GetActivePath(); + EXPECT_TRUE(path->path_preference().sequence() == 0); + EXPECT_TRUE(path->path_preference().preference() == PathPreference::HIGH); + EXPECT_TRUE(path->path_preference().ecmp() == false); + EXPECT_TRUE(path->path_preference().wait_for_traffic() == true); + EXPECT_TRUE(path->path_preference().static_preference() == true); +} + +//Verify that preference value change is reflected with +//static preference change +TEST_F(TestAap, StaticMachine_11) { + AddStaticPreference("intf1", 1, 100); + Ip4Address ip = Ip4Address::from_string("1.1.1.1"); + EXPECT_TRUE(RouteFind("vrf1", ip, 32)); + + VmInterface *vm_intf = VmInterfaceGet(1); + Inet4UnicastRouteEntry *rt = + RouteGet("vrf1", ip, 32); + const AgentPath *path = rt->GetActivePath(); + EXPECT_TRUE(path->path_preference().sequence() == 0); + EXPECT_TRUE(path->path_preference().preference() == PathPreference::LOW); + EXPECT_TRUE(path->path_preference().ecmp() == false); + EXPECT_TRUE(path->path_preference().wait_for_traffic() == true); + EXPECT_TRUE(path->path_preference().static_preference() == true); + + AddStaticPreference("intf1", 1, 200); + EXPECT_TRUE(path->path_preference().sequence() == 0); + EXPECT_TRUE(path->path_preference().preference() == PathPreference::HIGH); + EXPECT_TRUE(path->path_preference().ecmp() == false); + EXPECT_TRUE(path->path_preference().wait_for_traffic() == true); + EXPECT_TRUE(path->path_preference().static_preference() == true); + + AddStaticPreference("intf1", 1, 100); + EXPECT_TRUE(path->path_preference().preference() == PathPreference::LOW); + + //Delete static interface property + AddNode("virtual-machine-interface", "intf1", + 1, ""); + client->WaitForIdle(); + EXPECT_TRUE(path->path_preference().static_preference() == false); +} + int main(int argc, char *argv[]) { GETUSERARGS(); client = TestInit(init_file, ksync_init); diff --git a/src/vnsw/agent/oper/vm_interface.cc b/src/vnsw/agent/oper/vm_interface.cc index d3d8bd5449b..3a5967e9ccc 100644 --- a/src/vnsw/agent/oper/vm_interface.cc +++ b/src/vnsw/agent/oper/vm_interface.cc @@ -1870,20 +1870,6 @@ void VmInterface::AddRoute(const std::string &vrf_name, const Ip4Address &addr, vn_->GetName(), label_, sg_id_list, false, path_preference, gw_ip); - - Inet4UnicastRouteKey *rt_key = - new Inet4UnicastRouteKey(peer_.get(), vrf_name, addr, plen); - rt_key->sub_op_ = AgentKey::RESYNC; - - DBRequest req(DBRequest::DB_ENTRY_ADD_CHANGE); - req.key.reset(rt_key); - req.data.reset(new PathPreferenceData(path_preference)); - AgentRouteTable *table = - Agent::GetInstance()->vrf_table()->GetInet4UnicastRouteTable(vrf_name); - if (table) { - table->Process(req); - } - return; }