Skip to content

Commit

Permalink
Ensure flow-stickiness in case of ECMP with bridged forward flow and …
Browse files Browse the repository at this point in the history
…routed reverse flow

This is part of change needed to ensure flow-stickiness when forward flow
is bridged and reverse flow is routed. It has following parts,

Change to support ECMP Index management by VRouter

   VRouter now manages the ECMP Index for a flow. It keeps tracks source
   for a flow and updates the ECMP Index in reverse flow such that reverse
   flow are sent to origin.

   This commit supports ECMP Index management by VRouter. The key for
   reverse flow can potentially depend on the ECMP Index used for forward
   flow. Hence, Agent computes initial ECMP Index for forward flows still.
   However, agent does not compute ECMP Index for reverse flow.

Re-organized the ECMP and RPF management mode in the process.

Re-organized UT code for ECMP and RPF checks

Pending:
1. Skip VRF assignment for bridged packets
2. Support Unrestricted Proxy-ARP on interface

Change-Id: Iff3ee337ef9721df3e91336960691dc2480a22bb
Partial-Bug: #1648696
Partial-Bug: #1645978
  • Loading branch information
praveenkv committed Feb 28, 2017
1 parent 58a209e commit a9079bf
Show file tree
Hide file tree
Showing 39 changed files with 4,962 additions and 3,894 deletions.
51 changes: 51 additions & 0 deletions src/vnsw/agent/oper/nexthop.cc
Expand Up @@ -1422,6 +1422,57 @@ const NextHop* CompositeNH::GetLocalNextHop() const {
return NULL;
}

bool CompositeNH::HasVmInterface(const VmInterface *vmi) const {
ComponentNHList::const_iterator comp_nh_it =
component_nh_list_.begin();
for(;comp_nh_it != component_nh_list_.end(); comp_nh_it++) {
if ((*comp_nh_it) == NULL) {
continue;
}

if ((*comp_nh_it)->nh()->GetType() == NextHop::INTERFACE) {
const InterfaceNH *intf_nh = dynamic_cast<const InterfaceNH *>
((*comp_nh_it)->nh());
if (intf_nh->GetInterface() == vmi)
return true;
}
if ((*comp_nh_it)->nh()->GetType() == NextHop::VLAN) {
const VlanNH *vlan_nh = dynamic_cast<const VlanNH *>
((*comp_nh_it)->nh());
if (vlan_nh->GetInterface() == vmi)
return true;
}
}
return false;
}

uint32_t CompositeNH::PickMember(uint32_t seed, uint32_t affinity_index) const {
uint32_t idx = kInvalidComponentNHIdx;
size_t size = component_nh_list_.size();
if (size == 0) {
return idx;
}

if (affinity_index != kInvalidComponentNHIdx) {
const NextHop *nh = GetNH(affinity_index);
if (nh != NULL && nh->IsActive()) {
return affinity_index;
}
}

idx = seed % size;
while (component_nh_list_[idx].get() == NULL ||
component_nh_list_[idx]->nh() == NULL ||
component_nh_list_[idx]->nh()->IsActive() == false) {
idx = (idx + 1) % size;
if (idx == seed % size) {
idx = kInvalidComponentNHIdx;
break;
}
}
return idx;
}

NextHop *CompositeNHKey::AllocEntry() const {
VrfEntry *vrf = static_cast<VrfEntry *>
(Agent::GetInstance()->vrf_table()->Find(&vrf_key_, true));
Expand Down
4 changes: 4 additions & 0 deletions src/vnsw/agent/oper/nexthop.h
Expand Up @@ -1550,6 +1550,7 @@ class CompositeNH : public NextHop {
return active_count;
}

uint32_t PickMember(uint32_t seed, uint32_t affinity_index) const;
const NextHop* GetNH(uint32_t idx) const {
if (idx >= component_nh_list_.size()) {
return NULL;
Expand Down Expand Up @@ -1606,6 +1607,7 @@ class CompositeNH : public NextHop {
}
return idx;
}
bool HasVmInterface(const VmInterface *vmi) const;
bool GetIndex(ComponentNH &nh, uint32_t &idx) const;
const ComponentNH* Get(uint32_t idx) const {
return component_nh_list_[idx].get();
Expand Down Expand Up @@ -1647,7 +1649,9 @@ class CompositeNH : public NextHop {
/////////////////////////////////////////////////////////////////////////////
class NextHopTable : public AgentDBTable {
public:
static const uint32_t kRpfDisableIndex = 0;
static const uint32_t kRpfDiscardIndex = 2;

NextHopTable(DB *db, const std::string &name);
virtual ~NextHopTable();

Expand Down

0 comments on commit a9079bf

Please sign in to comment.