Skip to content

Commit

Permalink
* Copy SG and community id to ecmp path from local path
Browse files Browse the repository at this point in the history
If SG, community or tunnel map changes for a path copy that
updated list to ecmp path.
Test case for same.
Closes-bug:#1549541

Change-Id: If6db411fa4f977fa82741b5eaad1f2b926c60684
  • Loading branch information
naveen-n committed Feb 26, 2016
1 parent 0c3b917 commit eb156cc
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 31 deletions.
91 changes: 60 additions & 31 deletions src/vnsw/agent/oper/inet_unicast_route.cc
Expand Up @@ -352,40 +352,12 @@ bool InetUnicastRouteEntry::ModifyEcmpPath(const IpAddress &dest_addr,
ret = true;
}

path->set_tunnel_bmap(tunnel_bmap);
TunnelType::Type new_tunnel_type =
TunnelType::ComputeType(path->tunnel_bmap());
if (path->tunnel_type() != new_tunnel_type) {
path->set_tunnel_type(new_tunnel_type);
ret = true;
}

SecurityGroupList path_sg_list;
path_sg_list = path->sg_list();
if (path_sg_list != sg_list) {
path->set_sg_list(sg_list);
ret = true;
}

CommunityList path_communities;
path_communities = path->communities();
if (path_communities != communities) {
path->set_communities(communities);
ret = true;
}

if (path_preference != path->path_preference()) {
path->set_path_preference(path_preference);
ret = true;
}
ret = SyncEcmpPath(path, sg_list, communities, path_preference,
tunnel_bmap, ecmp_load_balance);

path->set_dest_vn_list(vn_list);
ret = true;
path->set_unresolved(false);
if (path->ecmp_load_balance() != ecmp_load_balance) {
path->set_ecmp_load_balance(ecmp_load_balance);
ret = true;
}

if (path->ChangeNH(agent, nh) == true)
ret = true;
Expand Down Expand Up @@ -571,6 +543,53 @@ bool InetUnicastRouteEntry::ReComputePathDeletion(AgentPath *path) {
return EcmpDeletePath(path);
}

bool InetUnicastRouteEntry::SyncEcmpPath(AgentPath *path,
const SecurityGroupList sg_list,
const CommunityList &communities,
const PathPreference &path_preference,
TunnelType::TypeBmap tunnel_bmap,
const EcmpLoadBalance
&ecmp_load_balance) {
if (!path) {
return false;
}

bool ret = false;
path->set_tunnel_bmap(tunnel_bmap);
TunnelType::Type new_tunnel_type =
TunnelType::ComputeType(path->tunnel_bmap());
if (path->tunnel_type() != new_tunnel_type) {
path->set_tunnel_type(new_tunnel_type);
ret = true;
}

SecurityGroupList path_sg_list;
path_sg_list = path->sg_list();
if (path_sg_list != sg_list) {
path->set_sg_list(sg_list);
ret = true;
}

CommunityList path_communities;
path_communities = path->communities();
if (path_communities != communities) {
path->set_communities(communities);
ret = true;
}

if (path_preference != path->path_preference()) {
path->set_path_preference(path_preference);
ret = true;
}

if (path->ecmp_load_balance() != ecmp_load_balance) {
path->set_ecmp_load_balance(ecmp_load_balance);
ret = true;
}

return ret;
}

// Handle add/update of a path in route.
// If there are more than one path of type LOCAL_VM_PORT_PEER, creates/updates
// Composite-NH for them
Expand Down Expand Up @@ -625,14 +644,24 @@ bool InetUnicastRouteEntry::EcmpAddPath(AgentPath *path) {
return false;
}

bool ret = false;
if (count == 2 && ecmp == NULL) {
// This is second path being added, make ECMP
AllocateEcmpPath(agent, vm_port_path, path);
ret = true;
} else if (count > 2) {
// ECMP already present, add/update Component-NH for the path
AppendEcmpPath(agent, path);
ret = true;
} else if (ecmp) {
AgentPath *ecmp_path = FindPath(agent->ecmp_peer());
ret = SyncEcmpPath(ecmp_path, path->sg_list(),
path->communities(), path->path_preference(),
path->tunnel_bmap(),
path->ecmp_load_balance());
}
return true;

return ret;
}

void InetUnicastRouteEntry::AppendEcmpPath(Agent *agent,
Expand Down
5 changes: 5 additions & 0 deletions src/vnsw/agent/oper/inet_unicast_route.h
Expand Up @@ -88,6 +88,11 @@ class InetUnicastRouteEntry : public AgentRoute {
DBRequest &nh_req,
Agent* agent,
AgentPath *path);
static bool SyncEcmpPath(AgentPath *path, SecurityGroupList sg_list,
const CommunityList &communities,
const PathPreference &path_preference,
TunnelType::TypeBmap tunnel_bmap,
const EcmpLoadBalance &ecmp_ecmp_load_balance);

const IpAddress &addr() const { return addr_; }
void set_addr(IpAddress addr) { addr_ = addr; };
Expand Down
35 changes: 35 additions & 0 deletions src/vnsw/agent/test/test_nh.cc
Expand Up @@ -2460,6 +2460,41 @@ TEST_F(CfgTest, EcmpNH_18) {
EXPECT_FALSE(RouteFind("vrf1", ip, 32));
}

TEST_F(CfgTest, EcmpNH_18) {
//Add interface
struct PortInfo input[] = {
{"vnet1", 1, "1.1.1.1", "00:00:00:01:01:01", 1, 1},
{"vnet2", 2, "1.1.1.1", "00:00:00:01:01:01", 1, 2},
};
CreateVmportWithEcmp(input, 2);
client->WaitForIdle();

Ip4Address ip = Ip4Address::from_string("1.1.1.1");
InetUnicastRouteEntry *rt = RouteGet("vrf1", ip, 32);
EXPECT_TRUE(rt != NULL);

//Update the SG for path
AddSg("sg1", 1);
AddAcl("acl1", 1);
AddLink("security-group", "sg1", "access-control-list", "acl1");
AddLink("virtual-machine-interface", "vnet1", "security-group", "sg1");
client->WaitForIdle();

EXPECT_TRUE(rt->GetActivePath()->sg_list().empty() == false);

DelLink("virtual-machine-interface", "vnet1", "security-group", "sg1");
DelLink("security-group", "sg1", "access-control-list", "acl1");
DelAcl("acl1");
DelNode("security-group", "sg1");
client->WaitForIdle();

EXPECT_TRUE(rt->GetActivePath()->sg_list().empty() == true);
DeleteVmportEnv(input, 1, true);
WAIT_FOR(100, 1000, (VrfFind("vrf1") == false));
client->WaitForIdle();
EXPECT_FALSE(RouteFind("vrf1", ip, 32));
}

int main(int argc, char **argv) {
GETUSERARGS();
client = TestInit(init_file, ksync_init);
Expand Down

0 comments on commit eb156cc

Please sign in to comment.