From b7e1392ccbdd3e898850161fe22ed5dbc3c4d34f Mon Sep 17 00:00:00 2001 From: Naveen N Date: Mon, 22 Dec 2014 06:04:42 -0800 Subject: [PATCH] * If there are more than 3 ecmp instance in same compute node and transition happens from non-ecmp to ecmp either due to active-active flag change or delay in instance-ip link being processed in oper DB, then when the first instance path change is being processed, there would already be 3 path, and logic expects ecmp peer path to be already present in that case, hence assert. Changed to login to count path with ecmp flag set only. Added a test case for the same, earlier test case used to verify only ecmp transition when there are 2 service instance. Closes-bug:#140484 Change-Id: I38fcc78405ea7ac557b825951d95b497b5389d49 --- src/vnsw/agent/oper/inet_unicast_route.cc | 4 ++- src/vnsw/agent/test/test_route.cc | 31 +++++++++++++++++++++++ src/vnsw/agent/test/test_util.cc | 5 ++-- 3 files changed, 37 insertions(+), 3 deletions(-) diff --git a/src/vnsw/agent/oper/inet_unicast_route.cc b/src/vnsw/agent/oper/inet_unicast_route.cc index 279e8b256a3..c31a4308122 100644 --- a/src/vnsw/agent/oper/inet_unicast_route.cc +++ b/src/vnsw/agent/oper/inet_unicast_route.cc @@ -377,6 +377,7 @@ bool InetUnicastRouteEntry::EcmpDeletePath(AgentPath *path) { if (it_path->peer() && it_path->peer()->GetType() == Peer::LOCAL_VM_PORT_PEER && + it_path->path_preference().ecmp() == true && it_path != path) count++; } @@ -461,7 +462,8 @@ bool InetUnicastRouteEntry::EcmpAddPath(AgentPath *path) { ecmp = it_path; if (it_path->peer() && - it_path->peer()->GetType() == Peer::LOCAL_VM_PORT_PEER) { + it_path->peer()->GetType() == Peer::LOCAL_VM_PORT_PEER && + it_path->path_preference().ecmp() == true) { count++; if (it_path != path) vm_port_path = it_path; diff --git a/src/vnsw/agent/test/test_route.cc b/src/vnsw/agent/test/test_route.cc index f0d1dde7356..05aed7ca647 100644 --- a/src/vnsw/agent/test/test_route.cc +++ b/src/vnsw/agent/test/test_route.cc @@ -1521,6 +1521,37 @@ TEST_F(RouteTest, PathPreference_1) { EXPECT_TRUE(VrfFind("vrf1", true) == false); } +TEST_F(RouteTest, NonEcmpToEcmpConversion) { + struct PortInfo input2[] = { + {"vnet11", 11, "2.1.1.1", "00:00:00:01:01:01", 8, 11}, + {"vnet12", 12, "2.1.1.1", "00:00:00:02:02:01", 8, 12}, + {"vnet13", 13, "2.1.1.1", "00:00:00:02:02:01", 8, 13}, + }; + //Add interface in non ecmp mode + CreateVmportEnv(input2, 3); + client->WaitForIdle(); + + Ip4Address ip = Ip4Address::from_string("2.1.1.1"); + InetUnicastRouteEntry *rt = RouteGet("vrf8", ip, 32); + EXPECT_TRUE(rt != NULL); + EXPECT_TRUE(rt->GetPathList().size() == 3); + EXPECT_TRUE(rt->GetActiveNextHop()->GetType() == NextHop::INTERFACE); + + CreateVmportWithEcmp(input2, 3); + client->WaitForIdle(); + EXPECT_TRUE(rt->GetPathList().size() == 4); + EXPECT_TRUE(rt->GetActiveNextHop()->GetType() == NextHop::COMPOSITE); + + CreateVmportEnv(input2, 3); + client->WaitForIdle(); + EXPECT_TRUE(rt->GetPathList().size() == 3); + EXPECT_TRUE(rt->GetActiveNextHop()->GetType() == NextHop::INTERFACE); + + DeleteVmportEnv(input2, 3, true); + client->WaitForIdle(); + EXPECT_TRUE(VrfFind("vrf8", true) == false); +} + int main(int argc, char *argv[]) { ::testing::InitGoogleTest(&argc, argv); GETUSERARGS(); diff --git a/src/vnsw/agent/test/test_util.cc b/src/vnsw/agent/test/test_util.cc index 6a77eca7e94..168a5a11330 100644 --- a/src/vnsw/agent/test/test_util.cc +++ b/src/vnsw/agent/test/test_util.cc @@ -1534,9 +1534,10 @@ void DelFloatingIpPool(const char *name) { } void AddInstanceIp(const char *name, int id, const char *addr) { - char buf[128]; + char buf[256]; - sprintf(buf, "%s", addr); + sprintf(buf, "%s" + "active-backup", addr); AddNode("instance-ip", name, id, buf); }