Skip to content

Commit

Permalink
[neighorch] VOQ encap index change handling (#1729)
Browse files Browse the repository at this point in the history
For the remote neighbors in the VOQ systems when there is change in the
encap index (due to syncd restart), the previously programmed remote
neighs should be re-written with the new changed encap index. The
current voq system neigh handling api in neighorch only checks for the
change of mac address. Because of this the change in the encap index is
ignored.
  • Loading branch information
vganesan-nokia authored and judyjoseph committed Aug 10, 2021
1 parent 0a2c6f8 commit 4a9c907
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 22 deletions.
124 changes: 102 additions & 22 deletions orchagent/neighorch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -783,16 +783,16 @@ bool NeighOrch::addNeighbor(const NeighborEntry &neighborEntry, const MacAddress
MuxOrch* mux_orch = gDirectory.get<MuxOrch*>();
bool hw_config = isHwConfigured(neighborEntry);

if (!hw_config && mux_orch->isNeighborActive(ip_address, macAddress, alias))
if (gMySwitchType == "voq")
{
if (gMySwitchType == "voq")
if (!addVoqEncapIndex(alias, ip_address, neighbor_attrs))
{
if (!addVoqEncapIndex(alias, ip_address, neighbor_attrs))
{
return false;
}
return false;
}
}

if (!hw_config && mux_orch->isNeighborActive(ip_address, macAddress, alias))
{
status = sai_neighbor_api->create_neighbor_entry(&neighbor_entry,
(uint32_t)neighbor_attrs.size(), neighbor_attrs.data());
if (status != SAI_STATUS_SUCCESS)
Expand Down Expand Up @@ -1230,8 +1230,43 @@ void NeighOrch::doVoqSystemNeighTask(Consumer &consumer)
}

if (m_syncdNeighbors.find(neighbor_entry) == m_syncdNeighbors.end() ||
m_syncdNeighbors[neighbor_entry].mac != mac_address)
m_syncdNeighbors[neighbor_entry].mac != mac_address ||
m_syncdNeighbors[neighbor_entry].voq_encap_index != encap_index)
{

if (m_syncdNeighbors.find(neighbor_entry) != m_syncdNeighbors.end() &&
m_syncdNeighbors[neighbor_entry].voq_encap_index != encap_index)
{

// Encap index changed. Set encap index attribute with new encap index
if (!updateVoqNeighborEncapIndex(neighbor_entry, encap_index))
{
// Setting encap index failed. SAI does not support change of encap index for
// existing neighbors. Remove the neighbor but do not errase from consumer sync
// buffer. The next iteration will add the neighbor back with new encap index

SWSS_LOG_NOTICE("VOQ encap index set failed for neighbor %s. Removing and re-adding", kfvKey(t).c_str());

//Remove neigh from SAI
if (removeNeighbor(neighbor_entry))
{
//neigh successfully deleted from SAI. Set STATE DB to signal to remove entries from kernel
m_stateSystemNeighTable->del(state_key);
}
else
{
SWSS_LOG_ERROR("Failed to remove voq neighbor %s from SAI during encap index update", kfvKey(t).c_str());
}
it++;
}
else
{
SWSS_LOG_NOTICE("VOQ encap index updated for neighbor %s", kfvKey(t).c_str());
it = consumer.m_toSync.erase(it);
}
continue;
}

//Add neigh to SAI
if (addNeighbor(neighbor_entry, mac_address))
{
Expand Down Expand Up @@ -1467,6 +1502,27 @@ void NeighOrch::voqSyncAddNeigh(string &alias, IpAddress &ip_address, const MacA
sai_attribute_t attr;
sai_status_t status;

// Get the encap index and store it for handling change of
// encap index for remote neighbors synced via CHASSIS_APP_DB

attr.id = SAI_NEIGHBOR_ENTRY_ATTR_ENCAP_INDEX;

status = sai_neighbor_api->get_neighbor_entry_attribute(&neighbor_entry, 1, &attr);
if (status != SAI_STATUS_SUCCESS)
{
SWSS_LOG_ERROR("Failed to get neighbor attribute for %s on %s, rv:%d", ip_address.to_string().c_str(), alias.c_str(), status);
return;
}

if (!attr.value.u32)
{
SWSS_LOG_ERROR("Invalid neighbor encap_index for %s on %s", ip_address.to_string().c_str(), alias.c_str());
return;
}

NeighborEntry nbrEntry = {ip_address, alias};
m_syncdNeighbors[nbrEntry].voq_encap_index = attr.value.u32;

//Sync only local neigh. Confirm for the local neigh and
//get the system port alias for key for syncing to CHASSIS_APP_DB
Port port;
Expand Down Expand Up @@ -1495,21 +1551,6 @@ void NeighOrch::voqSyncAddNeigh(string &alias, IpAddress &ip_address, const MacA
return;
}

attr.id = SAI_NEIGHBOR_ENTRY_ATTR_ENCAP_INDEX;

status = sai_neighbor_api->get_neighbor_entry_attribute(&neighbor_entry, 1, &attr);
if (status != SAI_STATUS_SUCCESS)
{
SWSS_LOG_ERROR("Failed to get neighbor attribute for %s on %s, rv:%d", ip_address.to_string().c_str(), alias.c_str(), status);
return;
}

if (!attr.value.u32)
{
SWSS_LOG_ERROR("Invalid neighbor encap_index for %s on %s", ip_address.to_string().c_str(), alias.c_str());
return;
}

vector<FieldValueTuple> attrs;

FieldValueTuple eiFv ("encap_index", to_string(attr.value.u32));
Expand Down Expand Up @@ -1555,3 +1596,42 @@ void NeighOrch::voqSyncDelNeigh(string &alias, IpAddress &ip_address)
string key = alias + m_tableVoqSystemNeighTable->getTableNameSeparator().c_str() + ip_address.to_string();
m_tableVoqSystemNeighTable->del(key);
}

bool NeighOrch::updateVoqNeighborEncapIndex(const NeighborEntry &neighborEntry, uint32_t encap_index)
{
SWSS_LOG_ENTER();

sai_status_t status;
IpAddress ip_address = neighborEntry.ip_address;
string alias = neighborEntry.alias;

sai_object_id_t rif_id = m_intfsOrch->getRouterIntfsId(alias);
if (rif_id == SAI_NULL_OBJECT_ID)
{
SWSS_LOG_INFO("Failed to get rif_id for %s", alias.c_str());
return false;
}

sai_neighbor_entry_t neighbor_entry;
neighbor_entry.rif_id = rif_id;
neighbor_entry.switch_id = gSwitchId;
copy(neighbor_entry.ip_address, ip_address);

sai_attribute_t neighbor_attr;
neighbor_attr.id = SAI_NEIGHBOR_ENTRY_ATTR_ENCAP_INDEX;
neighbor_attr.value.u32 = encap_index;

status = sai_neighbor_api->set_neighbor_entry_attribute(&neighbor_entry, &neighbor_attr);
if (status != SAI_STATUS_SUCCESS)
{
SWSS_LOG_ERROR("Failed to update voq encap index for neighbor %s on %s, rv:%d",
ip_address.to_string().c_str(), alias.c_str(), status);
return false;
}

SWSS_LOG_NOTICE("Updated voq encap index for neighbor %s on %s", ip_address.to_string().c_str(), alias.c_str());

m_syncdNeighbors[neighborEntry].voq_encap_index = encap_index;

return true;
}
2 changes: 2 additions & 0 deletions orchagent/neighorch.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ struct NeighborData
{
MacAddress mac;
bool hw_configured = false; // False means, entry is not written to HW
uint32_t voq_encap_index = 0;
};

/* NeighborTable: NeighborEntry, neighbor MAC address */
Expand Down Expand Up @@ -108,6 +109,7 @@ class NeighOrch : public Orch, public Subject, public Observer
bool addVoqEncapIndex(string &alias, IpAddress &ip, vector<sai_attribute_t> &neighbor_attrs);
void voqSyncAddNeigh(string &alias, IpAddress &ip_address, const MacAddress &mac, sai_neighbor_entry_t &neighbor_entry);
void voqSyncDelNeigh(string &alias, IpAddress &ip_address);
bool updateVoqNeighborEncapIndex(const NeighborEntry &neighborEntry, uint32_t encap_index);

bool resolveNeighborEntry(const NeighborEntry &, const MacAddress &);
void clearResolvedNeighborEntry(const NeighborEntry &);
Expand Down

0 comments on commit 4a9c907

Please sign in to comment.