Skip to content

Commit

Permalink
Enable policy on ECMP NH when any of component interfaces have policy
Browse files Browse the repository at this point in the history
enabled

Handle the following cases
1. When policy status of one of the component NH changes.
2. When a new ComponentNH is added
3. When an existing ComponentNH is removed
4. When ECMP route is added by BGP

Change-Id: Id8d8b871bd34639abf8f4d23f18b83e0b992a70e
Closes-Bug: #1566650
(cherry picked from commit 0e7d51b)
  • Loading branch information
ashoksr committed Aug 7, 2016
1 parent 6cfe009 commit d8de52a
Show file tree
Hide file tree
Showing 11 changed files with 202 additions and 86 deletions.
9 changes: 7 additions & 2 deletions src/vnsw/agent/controller/controller_peer.cc
Expand Up @@ -656,6 +656,7 @@ void AgentXmppChannel::AddEcmpRoute(string vrf_name, IpAddress prefix_addr,
}

ComponentNHKeyList comp_nh_list;
bool comp_nh_policy = false;
for (uint32_t i = 0; i < item->entry.next_hops.next_hop.size(); i++) {
std::string nexthop_addr =
item->entry.next_hops.next_hop[i].address;
Expand Down Expand Up @@ -689,7 +690,8 @@ void AgentXmppChannel::AddEcmpRoute(string vrf_name, IpAddress prefix_addr,
return;
}

DBEntryBase::KeyPtr key = mpls->nexthop()->GetDBRequestKey();
const NextHop *mpls_nh = mpls->nexthop();
DBEntryBase::KeyPtr key = mpls_nh->GetDBRequestKey();
NextHopKey *nh_key = static_cast<NextHopKey *>(key.release());
if (nh_key->GetType() != NextHop::COMPOSITE) {
//By default all component members of composite NH
Expand All @@ -701,6 +703,9 @@ void AgentXmppChannel::AddEcmpRoute(string vrf_name, IpAddress prefix_addr,
ComponentNHKeyPtr component_nh_key(new ComponentNHKey(label,
nh_key_ptr));
comp_nh_list.push_back(component_nh_key);
if (!comp_nh_policy) {
comp_nh_policy = mpls_nh->NexthopToInterfacePolicy();
}
}
} else {
encap = GetTypeBitmap
Expand All @@ -718,7 +723,7 @@ void AgentXmppChannel::AddEcmpRoute(string vrf_name, IpAddress prefix_addr,

// Build the NH request and then create route data to be passed
DBRequest nh_req(DBRequest::DB_ENTRY_ADD_CHANGE);
nh_req.key.reset(new CompositeNHKey(Composite::ECMP, false,
nh_req.key.reset(new CompositeNHKey(Composite::ECMP, comp_nh_policy,
comp_nh_list, vrf_name));
nh_req.data.reset(new CompositeNHData());
ControllerEcmpRoute *data =
Expand Down
7 changes: 6 additions & 1 deletion src/vnsw/agent/controller/controller_route_path.cc
Expand Up @@ -35,8 +35,13 @@ bool ControllerEcmpRoute::AddChangePath(Agent *agent, AgentPath *path,
CompositeNHKey *comp_key = static_cast<CompositeNHKey *>(nh_req_.key.get());
//Reorder the component NH list, and add a reference to local composite mpls
//label if any
if (path->ReorderCompositeNH(agent, comp_key) == false)
bool comp_nh_policy = comp_key->GetPolicy();
bool new_comp_nh_policy = false;
if (path->ReorderCompositeNH(agent, comp_key, new_comp_nh_policy) == false)
return false;
if (!comp_nh_policy) {
comp_key->SetPolicy(new_comp_nh_policy);
}
return InetUnicastRouteEntry::ModifyEcmpPath(dest_addr_, plen_, vn_list_,
label_, local_ecmp_nh_,
vrf_name_, sg_list_,
Expand Down
10 changes: 7 additions & 3 deletions src/vnsw/agent/oper/agent_path.cc
Expand Up @@ -253,7 +253,9 @@ bool AgentPath::Sync(AgentRoute *sync_route) {
composite_nh_key_.get() != NULL &&
local_ecmp_mpls_label_.get() != NULL) {
boost::scoped_ptr<CompositeNHKey> composite_nh_key(composite_nh_key_->Clone());
if (ReorderCompositeNH(agent, composite_nh_key.get())) {
bool comp_nh_policy = false;
if (ReorderCompositeNH(agent, composite_nh_key.get(), comp_nh_policy)) {
composite_nh_key->SetPolicy(comp_nh_policy);
if (ChangeCompositeNH(agent, composite_nh_key.get())) {
ret = true;
}
Expand Down Expand Up @@ -1269,7 +1271,8 @@ const MplsLabel* AgentPath::local_ecmp_mpls_label() const {
}

bool AgentPath::ReorderCompositeNH(Agent *agent,
CompositeNHKey *composite_nh_key) {
CompositeNHKey *composite_nh_key,
bool &comp_nh_policy) {
//Find local composite mpls label, if present
//This has to be done, before expanding component NH
BOOST_FOREACH(ComponentNHKeyPtr component_nh_key,
Expand Down Expand Up @@ -1317,7 +1320,8 @@ bool AgentPath::ReorderCompositeNH(Agent *agent,
//in that exact order,If B gets deleted,
//the new composite NH created should be A <NULL> C in that order,
//irrespective of the order user passed it in
composite_nh_key->Reorder(agent, label_, ComputeNextHop(agent));
comp_nh_policy = composite_nh_key->Reorder(agent, label_,
ComputeNextHop(agent));
//Copy the unchanged component NH list to path data
set_composite_nh_key(comp_key);
return true;
Expand Down
3 changes: 2 additions & 1 deletion src/vnsw/agent/oper/agent_path.h
Expand Up @@ -255,7 +255,8 @@ class AgentPath : public Path {
CompositeNHKey* composite_nh_key() {
return composite_nh_key_.get();
}
bool ReorderCompositeNH(Agent *agent, CompositeNHKey *nh);
bool ReorderCompositeNH(Agent *agent, CompositeNHKey *nh,
bool &comp_nh_policy);
bool ChangeCompositeNH(Agent *agent, CompositeNHKey *nh);
// Get nexthop-ip address to be used for path
const Ip4Address *NexthopIp(Agent *agent) const;
Expand Down
67 changes: 43 additions & 24 deletions src/vnsw/agent/oper/inet_unicast_route.cc
Expand Up @@ -449,15 +449,22 @@ AgentPath *InetUnicastRouteEntry::AllocateEcmpPath(Agent *agent,
// Allocate a new label for the ECMP path
uint32_t label = agent->mpls_table()->AllocLabel();

const NextHop* path1_nh = path1->ComputeNextHop(agent);
bool composite_nh_policy = path1_nh->NexthopToInterfacePolicy();

// Create Component NH to be added to ECMP path
DBEntryBase::KeyPtr key1 = path1->ComputeNextHop(agent)->GetDBRequestKey();
DBEntryBase::KeyPtr key1 = path1_nh->GetDBRequestKey();
NextHopKey *nh_key1 = static_cast<NextHopKey *>(key1.release());
std::auto_ptr<const NextHopKey> nh_akey1(nh_key1);
nh_key1->SetPolicy(false);
ComponentNHKeyPtr component_nh_data1(new ComponentNHKey(path1->label(),
nh_akey1));

DBEntryBase::KeyPtr key2 = path2->ComputeNextHop(agent)->GetDBRequestKey();
const NextHop* path2_nh = path2->ComputeNextHop(agent);
if (!composite_nh_policy) {
composite_nh_policy = path2_nh->NexthopToInterfacePolicy();
}
DBEntryBase::KeyPtr key2 = path2_nh->GetDBRequestKey();
NextHopKey *nh_key2 = static_cast<NextHopKey *>(key2.release());
std::auto_ptr<const NextHopKey> nh_akey2(nh_key2);
nh_key2->SetPolicy(false);
Expand All @@ -472,21 +479,22 @@ AgentPath *InetUnicastRouteEntry::AllocateEcmpPath(Agent *agent,
// It will also create CompositeNH if necessary
DBRequest nh_req(DBRequest::DB_ENTRY_ADD_CHANGE);
nh_req.key.reset(new CompositeNHKey(Composite::LOCAL_ECMP,
false, component_nh_list,
composite_nh_policy, component_nh_list,
vrf()->GetName()));
nh_req.data.reset(new CompositeNHData());

InetUnicastRouteEntry::ModifyEcmpPath(addr_, plen_, path2->dest_vn_list(),
label, true, vrf()->GetName(),
path2->sg_list(),
path2->communities(),
path2->path_preference(),
path2->tunnel_bmap(),
path2->ecmp_load_balance(),
nh_req, agent, path);
label, true, vrf()->GetName(),
path2->sg_list(),
path2->communities(),
path2->path_preference(),
path2->tunnel_bmap(),
path2->ecmp_load_balance(),
nh_req, agent, path);

//Make MPLS label point to Composite NH
MplsLabel::CreateEcmpLabel(agent, label, Composite::LOCAL_ECMP, component_nh_list,
MplsLabel::CreateEcmpLabel(agent, label, Composite::LOCAL_ECMP,
composite_nh_policy, component_nh_list,
vrf()->GetName());

RouteInfo rt_info;
Expand Down Expand Up @@ -763,7 +771,8 @@ void InetUnicastRouteEntry::AppendEcmpPath(Agent *agent,
AgentPath *ecmp_path = FindPath(agent->ecmp_peer());
assert(ecmp_path);

DBEntryBase::KeyPtr key = path->ComputeNextHop(agent)->GetDBRequestKey();
const NextHop* path_nh = path->ComputeNextHop(agent);
DBEntryBase::KeyPtr key = path_nh->GetDBRequestKey();
NextHopKey *nh_key = static_cast<NextHopKey *>(key.release());
std::auto_ptr<const NextHopKey> nh_akey(nh_key);
nh_key->SetPolicy(false);
Expand All @@ -772,12 +781,14 @@ void InetUnicastRouteEntry::AppendEcmpPath(Agent *agent,
ComponentNHKeyList component_nh_key_list;
const CompositeNH *comp_nh =
static_cast<const CompositeNH *>(ecmp_path->ComputeNextHop(agent));
component_nh_key_list = comp_nh->AddComponentNHKey(comp_nh_key_ptr);

bool composite_nh_policy = false;
component_nh_key_list = comp_nh->AddComponentNHKey(comp_nh_key_ptr,
composite_nh_policy);
// Form the request for Inet4UnicastEcmpRoute and invoke AddChangePath
DBRequest nh_req(DBRequest::DB_ENTRY_ADD_CHANGE);
nh_req.key.reset(new CompositeNHKey(Composite::LOCAL_ECMP,
false, component_nh_key_list,
composite_nh_policy,
component_nh_key_list,
vrf()->GetName()));
nh_req.data.reset(new CompositeNHData());

Expand All @@ -791,7 +802,8 @@ void InetUnicastRouteEntry::AppendEcmpPath(Agent *agent,

//Make MPLS label point to composite NH
MplsLabel::CreateEcmpLabel(agent, ecmp_path->label(), Composite::LOCAL_ECMP,
component_nh_key_list, vrf()->GetName());
composite_nh_policy, component_nh_key_list,
vrf()->GetName());

RouteInfo rt_info;
FillTrace(rt_info, AgentRoute::CHANGE_PATH, path);
Expand All @@ -811,24 +823,27 @@ bool InetUnicastRouteEntry::UpdateComponentNH(Agent *agent,
return false;
}
//Build ComponentNHKey for new path
DBEntryBase::KeyPtr key = path->ComputeNextHop(agent)->GetDBRequestKey();
const NextHop* path_nh = path->ComputeNextHop(agent);
DBEntryBase::KeyPtr key = path_nh->GetDBRequestKey();
NextHopKey *nh_key = static_cast<NextHopKey *>(key.get());
nh_key->SetPolicy(false);

ComponentNHKeyList component_nh_key_list;
const CompositeNH *comp_nh =
static_cast<const CompositeNH *>(ecmp_path->ComputeNextHop(agent));
bool composite_nh_policy = false;
bool updated = comp_nh->UpdateComponentNHKey(path->label(), nh_key,
component_nh_key_list);
component_nh_key_list,
composite_nh_policy);

if (!updated) {
return false;
}

// Form the request for Inet4UnicastEcmpRoute and invoke AddChangePath
DBRequest nh_req(DBRequest::DB_ENTRY_ADD_CHANGE);
nh_req.key.reset(new CompositeNHKey(Composite::LOCAL_ECMP,
false, component_nh_key_list,
composite_nh_policy,
component_nh_key_list,
vrf()->GetName()));
nh_req.data.reset(new CompositeNHData());

Expand All @@ -843,7 +858,8 @@ bool InetUnicastRouteEntry::UpdateComponentNH(Agent *agent,

//Make MPLS label point to updated composite NH
MplsLabel::CreateEcmpLabel(agent, ecmp_path->label(), Composite::LOCAL_ECMP,
component_nh_key_list, vrf()->GetName());
composite_nh_policy, component_nh_key_list,
vrf()->GetName());

RouteInfo rt_info;
FillTrace(rt_info, AgentRoute::CHANGE_PATH, path);
Expand All @@ -865,14 +881,16 @@ void InetUnicastRouteEntry::DeleteComponentNH(Agent *agent, AgentPath *path) {
ComponentNHKeyPtr comp_nh_key_ptr(new ComponentNHKey(path->label(), nh_akey));

ComponentNHKeyList component_nh_key_list;
bool comp_nh_policy = false;
const CompositeNH *comp_nh =
static_cast<const CompositeNH *>(ecmp_path->ComputeNextHop(agent));
component_nh_key_list = comp_nh->DeleteComponentNHKey(comp_nh_key_ptr);
component_nh_key_list = comp_nh->DeleteComponentNHKey(comp_nh_key_ptr,
comp_nh_policy);

// Form the request for Inet4UnicastEcmpRoute and invoke AddChangePath
DBRequest nh_req(DBRequest::DB_ENTRY_ADD_CHANGE);
nh_req.key.reset(new CompositeNHKey(Composite::LOCAL_ECMP,
false, component_nh_key_list,
comp_nh_policy, component_nh_key_list,
vrf()->GetName()));
nh_req.data.reset(new CompositeNHData());

Expand All @@ -889,7 +907,8 @@ void InetUnicastRouteEntry::DeleteComponentNH(Agent *agent, AgentPath *path) {

//Make MPLS label point to composite NH
MplsLabel::CreateEcmpLabel(agent, ecmp_path->label(), Composite::LOCAL_ECMP,
component_nh_key_list, vrf()->GetName());
comp_nh_policy, component_nh_key_list,
vrf()->GetName());

RouteInfo rt_info;
FillTrace(rt_info, AgentRoute::CHANGE_PATH, path);
Expand Down
4 changes: 2 additions & 2 deletions src/vnsw/agent/oper/mpls.cc
Expand Up @@ -202,7 +202,7 @@ void MplsLabel::CreateVPortLabel(const Agent *agent,
}

void MplsLabel::CreateEcmpLabel(const Agent *agent,
uint32_t label, COMPOSITETYPE type,
uint32_t label, COMPOSITETYPE type, bool policy,
ComponentNHKeyList &component_nh_key_list,
const std::string vrf_name) {
DBRequest req;
Expand All @@ -211,7 +211,7 @@ void MplsLabel::CreateEcmpLabel(const Agent *agent,
MplsLabelKey *key = new MplsLabelKey(MplsLabel::VPORT_NH, label);
req.key.reset(key);

MplsLabelData *data = new MplsLabelData(type, false, component_nh_key_list,
MplsLabelData *data = new MplsLabelData(type, policy, component_nh_key_list,
vrf_name);
req.data.reset(data);

Expand Down
3 changes: 2 additions & 1 deletion src/vnsw/agent/oper/mpls.h
Expand Up @@ -55,7 +55,8 @@ class MplsLabel : AgentRefCount<MplsLabel>, public AgentDBEntry {
bool policy,
InterfaceNHFlags::Type type,
const MacAddress &mac);
static void CreateEcmpLabel(const Agent *agent, uint32_t label, COMPOSITETYPE type,
static void CreateEcmpLabel(const Agent *agent, uint32_t label,
COMPOSITETYPE type, bool policy,
ComponentNHKeyList &component_nh_key_list,
const std::string vrf_name);
// Delete MPLS Label entry
Expand Down

0 comments on commit d8de52a

Please sign in to comment.