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; }