Skip to content

Commit

Permalink
* Track static and floating ip preference based on instance ip
Browse files Browse the repository at this point in the history
1> Floating ip, static route and allowed address pair in ecmp
   mode would have preference published based on instance-ip
   preference
2> If allowed-address pair address is configured in active-stdby
   mode, run path preference algorithm
Test case for same
Closes-bug:#1462093,#1461787

Change-Id: Ied0df91788b6fb4dc289ced5f43548da33ca34cc
(cherry picked from commit 590e031)
  • Loading branch information
naveen-n committed Aug 20, 2015
1 parent a7a4e3c commit 9eabafe
Show file tree
Hide file tree
Showing 15 changed files with 566 additions and 80 deletions.
3 changes: 2 additions & 1 deletion src/vnsw/agent/controller/controller_peer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -838,7 +838,8 @@ void AgentXmppChannel::AddEvpnRoute(const std::string &vrf_name,
rt_table->AddReceiveRouteReq(bgp_peer_id(), vrf_name,
label, mac, ip_addr,
item->entry.nlri.ethernet_tag,
item->entry.virtual_network);
item->entry.virtual_network,
path_preference);
return;
}

Expand Down
7 changes: 6 additions & 1 deletion src/vnsw/agent/oper/agent_path.cc
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,11 @@ bool L2ReceiveRoute::AddChangePath(Agent *agent, AgentPath *path,
ret = true;
}

if (path->path_preference().ConfigChanged(path_preference_)) {
path->set_path_preference(path_preference_);
ret = true;
}

if (path->ChangeNH(agent, agent->nexthop_table()->l2_receive_nh()) == true)
ret = true;

Expand Down Expand Up @@ -717,7 +722,7 @@ bool VlanNhRoute::AddChangePath(Agent *agent, AgentPath *path,

//Copy over entire path preference structure, whenever there is a
//transition from active-active to active-backup struture
if (path->path_preference().ecmp() != path_preference_.ecmp()) {
if (path->path_preference().ConfigChanged(path_preference_)) {
path->set_path_preference(path_preference_);
ret = true;
}
Expand Down
47 changes: 42 additions & 5 deletions src/vnsw/agent/oper/agent_path.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,12 @@ class PathPreference {
HIGH = 200
};
PathPreference(): sequence_(0), preference_(LOW),
wait_for_traffic_(true), ecmp_(false), static_preference_(false) {}
wait_for_traffic_(true), ecmp_(false), static_preference_(false),
dependent_ip_(Ip4Address(0)) {}
PathPreference(uint32_t sequence, Preference preference,
bool wait_for_traffic, bool ecmp): sequence_(sequence),
preference_(preference), wait_for_traffic_(wait_for_traffic),
ecmp_(ecmp), static_preference_(false) {}
ecmp_(ecmp), static_preference_(false), dependent_ip_(Ip4Address(0)) {}
uint32_t sequence() const { return sequence_;}
Preference preference() const { return preference_;}
bool wait_for_traffic() const {
Expand All @@ -41,10 +42,25 @@ class PathPreference {
return ecmp_;
}

bool is_ecmp() const {
if (ecmp_ == true || (preference_ == HIGH && sequence_ == 0)) {
return true;
}
return false;
}

bool static_preference() const {
return static_preference_;
}

const IpAddress& dependent_ip() const {
return dependent_ip_;
}

const std::string& vrf() const {
return vrf_;
}

void set_sequence(uint32_t sequence) {
sequence_ = sequence;
}
Expand All @@ -62,6 +78,14 @@ class PathPreference {
static_preference_ = static_pref;
}

void set_dependent_ip(const IpAddress &ip) {
dependent_ip_ = ip;
}

void set_vrf(const std::string &vrf) {
vrf_ = vrf;
}

bool operator!=(const PathPreference &rhs) const {
return (sequence_ != rhs.sequence_ || preference_ != rhs.preference_
|| wait_for_traffic_ != rhs.wait_for_traffic_
Expand All @@ -83,24 +107,36 @@ class PathPreference {
//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 ConfigChanged(const 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;
} else if (dependent_ip_ != rhs.dependent_ip_) {
ret = true;
}
return ret;
}

bool IsDependentRt(void) const {
if (dependent_ip_ != Ip4Address(0)) {
return true;
}
return false;
}


private:
uint32_t sequence_;
Preference preference_;
bool wait_for_traffic_;
bool ecmp_;
bool static_preference_;
IpAddress dependent_ip_;
std::string vrf_;
};

//Route data to change preference and sequence number of path
Expand Down Expand Up @@ -460,9 +496,9 @@ class HostRoute : public AgentRouteData {
class L2ReceiveRoute : public AgentRouteData {
public:
L2ReceiveRoute(const std::string &dest_vn_name, uint32_t vxlan_id,
uint32_t mpls_label) :
uint32_t mpls_label, const PathPreference &pref) :
AgentRouteData(false), dest_vn_name_(dest_vn_name),
vxlan_id_(vxlan_id), mpls_label_(mpls_label) {
vxlan_id_(vxlan_id), mpls_label_(mpls_label), path_preference_(pref) {
}
virtual ~L2ReceiveRoute() { }
virtual bool AddChangePath(Agent *agent, AgentPath *path,
Expand All @@ -474,6 +510,7 @@ class L2ReceiveRoute : public AgentRouteData {
std::string dest_vn_name_;
uint32_t vxlan_id_;
uint32_t mpls_label_;
const PathPreference path_preference_;
DISALLOW_COPY_AND_ASSIGN(L2ReceiveRoute);
};

Expand Down
12 changes: 10 additions & 2 deletions src/vnsw/agent/oper/agent_route.cc
Original file line number Diff line number Diff line change
Expand Up @@ -325,9 +325,17 @@ void AgentRouteTable::Input(DBTablePartition *part, DBClient *client,
if (data) {
path = key->peer() ? rt->FindPath(key->peer()) : NULL;
if (path != NULL) {
bool ecmp = path->path_preference().is_ecmp();
// AddChangePath should be triggered only if a path
// is available from the given peer
notify = data->AddChangePath(agent_, path, rt);
//If a path transition from ECMP to non ECMP
//remote the path from ecmp peer
if (ecmp && ecmp != path->path_preference().is_ecmp()) {
rt->ReComputePathDeletion(path);
} else if (rt->ReComputePathAdd(path)) {
notify = true;
}
}
} else {
//Ignore RESYNC if received on non-existing
Expand Down Expand Up @@ -388,11 +396,11 @@ void AgentRouteTable::Input(DBTablePartition *part, DBClient *client,
} else {
// Let path know of route change and update itself
path->set_is_stale(false);
bool ecmp = path->path_preference().ecmp();
bool ecmp = path->path_preference().is_ecmp();
notify = rt->ProcessPath(agent_, part, path, data);
//If a path transition from ECMP to non ECMP
//remote the path from ecmp peer
if (ecmp && ecmp != path->path_preference().ecmp()) {
if (ecmp && ecmp != path->path_preference().is_ecmp()) {
rt->ReComputePathDeletion(path);
}

Expand Down
4 changes: 2 additions & 2 deletions src/vnsw/agent/oper/bridge_route.cc
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ void BridgeAgentRouteTable::AddBridgeReceiveRouteReq(const Peer *peer,
const string &vn_name) {
DBRequest req(DBRequest::DB_ENTRY_ADD_CHANGE);
req.key.reset(new BridgeRouteKey(peer, vrf_name, mac, vxlan_id));
req.data.reset(new L2ReceiveRoute(vn_name, vxlan_id, 0));
req.data.reset(new L2ReceiveRoute(vn_name, vxlan_id, 0, PathPreference()));
Enqueue(&req);
}

Expand All @@ -114,7 +114,7 @@ void BridgeAgentRouteTable::AddBridgeReceiveRoute(const Peer *peer,
const string &vn_name) {
DBRequest req(DBRequest::DB_ENTRY_ADD_CHANGE);
req.key.reset(new BridgeRouteKey(peer, vrf_name, mac, vxlan_id));
req.data.reset(new L2ReceiveRoute(vn_name, vxlan_id, 0));
req.data.reset(new L2ReceiveRoute(vn_name, vxlan_id, 0, PathPreference()));
Process(req);
}

Expand Down
10 changes: 6 additions & 4 deletions src/vnsw/agent/oper/evpn_route.cc
Original file line number Diff line number Diff line change
Expand Up @@ -108,11 +108,12 @@ void EvpnAgentRouteTable::AddReceiveRouteReq(const Peer *peer,
const MacAddress &mac,
const IpAddress &ip_addr,
uint32_t ethernet_tag,
const string &vn_name) {
const string &vn_name,
const PathPreference &pref) {
DBRequest req(DBRequest::DB_ENTRY_ADD_CHANGE);
req.key.reset(new EvpnRouteKey(peer, vrf_name, mac, ip_addr,
ethernet_tag));
req.data.reset(new L2ReceiveRoute(vn_name, ethernet_tag, label));
req.data.reset(new L2ReceiveRoute(vn_name, ethernet_tag, label, pref));
Enqueue(&req);
}

Expand All @@ -122,11 +123,12 @@ void EvpnAgentRouteTable::AddReceiveRoute(const Peer *peer,
const MacAddress &mac,
const IpAddress &ip_addr,
uint32_t ethernet_tag,
const string &vn_name) {
const string &vn_name,
const PathPreference &pref) {
DBRequest req(DBRequest::DB_ENTRY_ADD_CHANGE);
req.key.reset(new EvpnRouteKey(peer, vrf_name, mac, ip_addr,
ethernet_tag));
req.data.reset(new L2ReceiveRoute(vn_name, ethernet_tag, label));
req.data.reset(new L2ReceiveRoute(vn_name, ethernet_tag, label, pref));
Process(req);
}

Expand Down
6 changes: 4 additions & 2 deletions src/vnsw/agent/oper/evpn_route.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,13 @@ class EvpnAgentRouteTable : public AgentRouteTable {
void AddReceiveRouteReq(const Peer *peer, const std::string &vrf_name,
uint32_t label, const MacAddress &mac,
const IpAddress &ip_addr, uint32_t ethernet_tag,
const std::string &vn_name);
const std::string &vn_name,
const PathPreference &pref);
void AddReceiveRoute(const Peer *peer, const std::string &vrf_name,
uint32_t label, const MacAddress &mac,
const IpAddress &ip_addr, uint32_t ethernet_tag,
const std::string &vn_name);
const std::string &vn_name,
const PathPreference &pref);
void AddLocalVmRouteReq(const Peer *peer,
const std::string &vrf_name,
const MacAddress &mac,
Expand Down
6 changes: 3 additions & 3 deletions src/vnsw/agent/oper/inet_unicast_route.cc
Original file line number Diff line number Diff line change
Expand Up @@ -461,7 +461,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_preference().is_ecmp() == true &&
it_path != path)
count++;
}
Expand Down Expand Up @@ -561,7 +561,7 @@ bool InetUnicastRouteEntry::EcmpAddPath(AgentPath *path) {

// We are interested only in path from LOCAL_VM_PORT_PEER
if (path->peer()->GetType() != Peer::LOCAL_VM_PORT_PEER ||
path->path_preference().ecmp() == false) {
path->path_preference().is_ecmp() == false) {
return false;
}

Expand All @@ -583,7 +583,7 @@ bool InetUnicastRouteEntry::EcmpAddPath(AgentPath *path) {

if (it_path->peer() &&
it_path->peer()->GetType() == Peer::LOCAL_VM_PORT_PEER &&
it_path->path_preference().ecmp() == true) {
it_path->path_preference().is_ecmp() == true) {
count++;
if (it_path != path)
vm_port_path = it_path;
Expand Down

0 comments on commit 9eabafe

Please sign in to comment.