From cfde6909bd93b91851e4cbcfcd507c5f3bd83b9b 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 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 403afa31cfb..91548c2a34a 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 01037a9ff5e..7d8a3095137 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; }