Skip to content

Commit

Permalink
Fix VRF update handling for loopback interfaces in IntfsOrch
Browse files Browse the repository at this point in the history
Signed-off-by: Sai Singamala <[email protected]>
  • Loading branch information
ram25794 committed Jan 7, 2025
1 parent c20902f commit ad22bcf
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 0 deletions.
13 changes: 13 additions & 0 deletions orchagent/intfsorch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -846,6 +846,19 @@ void IntfsOrch::doTask(Consumer &consumer)
m_syncdIntfses[alias] = intfs_entry;
m_vrfOrch->increaseVrfRefCount(vrf_id);
}
else if (m_syncdIntfses[alias].vrf_id != vrf_id)
{
if (m_syncdIntfses[alias].ip_addresses.size() == 0)
{
m_vrfOrch->decreaseVrfRefCount(m_syncdIntfses[alias].vrf_id);
m_vrfOrch->increaseVrfRefCount(vrf_id);
m_syncdIntfses[alias].vrf_id = vrf_id;
}
else
{
SWSS_LOG_ERROR("Failed to set interface '%s' to VRF ID '%d' because it has IP addresses associated with it.", alias.c_str(), vrf_id);
}
}
}
else
{
Expand Down
58 changes: 58 additions & 0 deletions tests/mock_tests/intfsorch_ut.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -330,5 +330,63 @@ namespace intfsorch_test
static_cast<Orch *>(gIntfsOrch)->doTask();
ASSERT_EQ(current_create_count + 1, create_rif_count);
ASSERT_EQ(current_remove_count + 1, remove_rif_count);
};

TEST_F(IntfsOrchTest, IntfsOrchVrfUpdate)
{
//create a new vrf
std::deque<KeyOpFieldsValuesTuple> entries;
entries.push_back({"Vrf-Blue", "SET", { {"NULL", "NULL"}}});
auto consumer = dynamic_cast<Consumer *>(gVrfOrch->getExecutor(APP_VRF_TABLE_NAME));
consumer->addToSync(entries);
static_cast<Orch *>(gVrfOrch)->doTask();
ASSERT_TRUE(gVrfOrch->isVRFexists("Vrf-Blue"));
auto new_vrf_reference_count = gVrfOrch->getVrfRefCount("Vrf-Blue");
ASSERT_EQ(new_vrf_reference_count, 0);

// create an interface
entries.clear();
entries.push_back({"Loopback2", "SET", {}});
consumer = dynamic_cast<Consumer *>(gIntfsOrch->getExecutor(APP_INTF_TABLE_NAME));
consumer->addToSync(entries);
static_cast<Orch *>(gIntfsOrch)->doTask();
IntfsTable m_syncdIntfses = gIntfsOrch->getSyncdIntfses();
ASSERT_EQ(m_syncdIntfses["Loopback2"].vrf_id, gVirtualRouterId);

// change vrf and check if it worked
entries.clear();
entries.push_back({"Loopback2", "SET", { {"vrf_name", "Vrf-Blue"}}});
consumer = dynamic_cast<Consumer *>(gIntfsOrch->getExecutor(APP_INTF_TABLE_NAME));
consumer->addToSync(entries);
static_cast<Orch *>(gIntfsOrch)->doTask();
auto new_vrf_updated_reference_count = gVrfOrch->getVrfRefCount("Vrf-Blue");
ASSERT_EQ(new_vrf_reference_count + 1, new_vrf_updated_reference_count);
m_syncdIntfses = gIntfsOrch->getSyncdIntfses();
ASSERT_EQ(m_syncdIntfses["Loopback2"].vrf_id, gVrfOrch->getVRFid("Vrf-Blue"));

// create an interface
entries.clear();
entries.push_back({"Loopback3", "SET", {}});
consumer = dynamic_cast<Consumer *>(gIntfsOrch->getExecutor(APP_INTF_TABLE_NAME));
consumer->addToSync(entries);
static_cast<Orch *>(gIntfsOrch)->doTask();
m_syncdIntfses = gIntfsOrch->getSyncdIntfses();
ASSERT_EQ(m_syncdIntfses["Loopback3"].vrf_id, gVirtualRouterId);

// Add IP address to the interface
entries.clear();
entries.push_back({"Loopback3:3.3.3.3/32", "SET", {{"scope", "global"},{"family", "IPv4"}}});
consumer = dynamic_cast<Consumer *>(gIntfsOrch->getExecutor(APP_INTF_TABLE_NAME));
consumer->addToSync(entries);
static_cast<Orch *>(gIntfsOrch)->doTask();

// change vrf and check it doesn't affect the interface due to existing IP
entries.clear();
entries.push_back({"Loopback3", "SET", { {"vrf_name", "Vrf-Blue"}}});
consumer = dynamic_cast<Consumer *>(gIntfsOrch->getExecutor(APP_INTF_TABLE_NAME));
consumer->addToSync(entries);
static_cast<Orch *>(gIntfsOrch)->doTask();
m_syncdIntfses = gIntfsOrch->getSyncdIntfses();
ASSERT_EQ(m_syncdIntfses["Loopback3"].vrf_id, gVirtualRouterId);
}
}

0 comments on commit ad22bcf

Please sign in to comment.