Skip to content

Commit

Permalink
* Path preference change was enqueued every time, interface config
Browse files Browse the repository at this point in the history
  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
  • Loading branch information
naveen-n committed Dec 9, 2014
1 parent 5ce29bd commit 662cc98
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 17 deletions.
13 changes: 10 additions & 3 deletions src/vnsw/agent/oper/agent_path.cc
Expand Up @@ -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;
}
Expand Down
17 changes: 17 additions & 0 deletions src/vnsw/agent/oper/agent_path.h
Expand Up @@ -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_;
Expand Down
66 changes: 66 additions & 0 deletions src/vnsw/agent/oper/test/test_aap.cc
Expand Up @@ -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 << "<virtual-machine-interface-properties>";
buf << "<local-preference>";
buf << value;
buf << "</local-preference>";
buf << "</virtual-machine-interface-properties>";
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();
Expand Down Expand Up @@ -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);
Expand Down
14 changes: 0 additions & 14 deletions src/vnsw/agent/oper/vm_interface.cc
Expand Up @@ -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;
}

Expand Down

0 comments on commit 662cc98

Please sign in to comment.