From 662cc98755a1934477cc2d1f48499e3fce41640b Mon Sep 17 00:00:00 2001 From: Naveen N Date: Tue, 9 Dec 2014 03:09:53 -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 Change-Id: If82fe39ee0be7ecdd8671150f886dcb0402d3b43 --- 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 6492a5c70f9..6ba188a9389 100644 --- a/src/vnsw/agent/oper/agent_path.cc +++ b/src/vnsw/agent/oper/agent_path.cc @@ -408,9 +408,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 721d82ad0e0..59b0817d09e 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 710816dd92e..6a50903c5fb 100644 --- a/src/vnsw/agent/oper/test/test_aap.cc +++ b/src/vnsw/agent/oper/test/test_aap.cc @@ -84,6 +84,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(); @@ -467,6 +482,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); + InetUnicastRouteEntry *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); + InetUnicastRouteEntry *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 284c7e6f152..0b2367d3b0f 100644 --- a/src/vnsw/agent/oper/vm_interface.cc +++ b/src/vnsw/agent/oper/vm_interface.cc @@ -2066,20 +2066,6 @@ void VmInterface::AddRoute(const std::string &vrf_name, const IpAddress &addr, dest_vn, label_, sg_id_list, false, path_preference, gw_ip); - - InetUnicastRouteKey *rt_key = - new InetUnicastRouteKey(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; }