Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

McLAG Stale Static mac is present in hardware even after the port-channel is removed from VLAN #2610

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 64 additions & 1 deletion orchagent/fdborch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1149,6 +1149,48 @@ void FdbOrch::updatePortOperState(const PortOperStateUpdate& update)
return;
}

void FdbOrch::flushMclagRemoteFDBEntries(sai_object_id_t bridge_port_oid,
Port &vlan)
{
SWSS_LOG_DEBUG("Mclag remote mac flush:Input port = 0x%" PRIx64", bv_id=0x%" PRIx64,
bridge_port_oid, vlan.m_vlan_info.vlan_oid);
Port port;
for (auto itr = m_entries.begin(); itr != m_entries.end();)
{
FdbData fdbData = itr->second;
FdbEntry entry;
entry.mac = itr->first.mac;
entry.bv_id = itr->first.bv_id;


SWSS_LOG_DEBUG("FDB DB:origin = %d, port = 0x%" PRIx64", mac=%s, bv_id=0x%" PRIx64,
itr->second.origin, fdbData.bridge_port_id,
itr->first.mac.to_string().c_str(), itr->first.bv_id);

++itr;
if ((fdbData.bridge_port_id == bridge_port_oid) &&
(entry.bv_id == vlan.m_vlan_info.vlan_oid) &&
(fdbData.origin == FDB_ORIGIN_MCLAG_ADVERTIZED))
{

if (!removeFdbEntry(entry, fdbData.origin))
{
SWSS_LOG_ERROR("remove FDB entry fail mac=%s, bv_id=0x%" PRIx64,
entry.mac.to_string().c_str(), entry.bv_id);

} else {
SWSS_LOG_NOTICE("removed FDB entry. mac=%s, bv_id=0x%" PRIx64,
entry.mac.to_string().c_str(), entry.bv_id);
}
if (m_portsOrch->getPortByBridgePortId(fdbData.bridge_port_id, port))
{
saved_fdb_entries[port.m_alias].push_back(
{entry.mac, vlan.m_vlan_info.vlan_id, fdbData});
}
}
}
}

void FdbOrch::updateVlanMember(const VlanMemberUpdate& update)
{
SWSS_LOG_ENTER();
Expand All @@ -1157,6 +1199,7 @@ void FdbOrch::updateVlanMember(const VlanMemberUpdate& update)
{
swss::Port vlan = update.vlan;
swss::Port port = update.member;
flushMclagRemoteFDBEntries(port.m_bridge_port_id,vlan);
flushFDBEntries(port.m_bridge_port_id, vlan.m_vlan_info.vlan_oid);
notifyObserversFDBFlush(port, vlan.m_vlan_info.vlan_oid);
return;
Expand Down Expand Up @@ -1206,10 +1249,20 @@ bool FdbOrch::addFdbEntry(const FdbEntry& entry, const string& port_name,
return false;
}

auto it = m_entries.find(entry);
/* Retry until port is created */
if (!m_portsOrch->getPort(port_name, port) || (port.m_bridge_port_id == SAI_NULL_OBJECT_ID))
{
SWSS_LOG_INFO("Saving a fdb entry until port %s becomes active", port_name.c_str());
/*
* Mclag Synced mac scenario
* -> mac moved from ICL to Nonmember VLT (after shut/no shut on VLT portchannel)
* delete the existing entry and save the fdb entries and wait VLT becomes member of VLAN
*/
if (it != m_entries.end()) {
removeFdbEntry(entry, it->second.origin);
}

saved_fdb_entries[port_name].push_back({entry.mac,
vlan.m_vlan_info.vlan_id, fdbData});
return true;
Expand All @@ -1221,13 +1274,24 @@ bool FdbOrch::addFdbEntry(const FdbEntry& entry, const string& port_name,
{
end_point_ip = fdbData.remote_ip;
}

/* Retry until port is member of vlan*/
if (!m_portsOrch->isVlanMember(vlan, port, end_point_ip))
{
SWSS_LOG_INFO("Saving a fdb entry until port %s becomes vlan %s member", port_name.c_str(), vlan.m_alias.c_str());
/*
* Mclag Synced mac scenario
* -> mac moved from ICL to Nonmember VLT (after shut/no shut on VLT portchannel)
* delete the existing entry and save the fdb entries and wait VLT becomes member of VLAN
*/
if (it != m_entries.end()) {
removeFdbEntry(entry, it->second.origin);
}
saved_fdb_entries[port_name].push_back({entry.mac,
vlan.m_vlan_info.vlan_id, fdbData});
return true;
} else {
deleteFdbEntryFromSavedFDB (entry.mac, vlan.m_vlan_info.vlan_id, fdbData.origin);
}

sai_status_t status;
Expand All @@ -1242,7 +1306,6 @@ bool FdbOrch::addFdbEntry(const FdbEntry& entry, const string& port_name,
FdbOrigin oldOrigin = FDB_ORIGIN_INVALID ;
bool macUpdate = false;

auto it = m_entries.find(entry);
if (it != m_entries.end())
{
/* get existing port and type */
Expand Down
2 changes: 2 additions & 0 deletions orchagent/fdborch.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ class FdbOrch: public Orch, public Subject, public Observer
void flushFDBEntries(sai_object_id_t bridge_port_oid,
sai_object_id_t vlan_oid);
void notifyObserversFDBFlush(Port &p, sai_object_id_t&);
void flushMclagRemoteFDBEntries(sai_object_id_t bridge_port_oid,
Port &vlan);

private:
PortsOrch *m_portsOrch;
Expand Down
273 changes: 272 additions & 1 deletion tests/test_mclag_fdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -483,7 +483,278 @@ def test_mclagFdb_static_mac_dynamic_move_reject(dvs, testlog):
"MCLAG_FDB_TABLE", "Vlan200:3C:85:99:5E:00:01",
)

# Test-12 Verify cleanup of the basic config.
# Test-12 Remote Static MAC Add Vlan member remove and add

@pytest.mark.dev_sanity
def test_mclagFdb_remote_static_mac_add_member_remove_add(dvs, testlog):
dvs.setup_db()

create_entry_pst(
dvs.pdb,
"MCLAG_FDB_TABLE", "Vlan200:3C:85:99:5E:00:01",
[
("port", "PortChannel0005"),
("type", "static"),
]
)

# check that the FDB entry was inserted into ASIC DB
assert how_many_entries_exist(dvs.adb, "ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY") == 1, "The MCLAG static fdb entry not inserted to ASIC"

ok, extra = dvs.is_fdb_entry_exists(dvs.adb, "ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY",
[("mac", "3C:85:99:5E:00:01"), ("bvid", str(dvs.getVlanOid("200")))],
[("SAI_FDB_ENTRY_ATTR_TYPE", "SAI_FDB_ENTRY_TYPE_STATIC")]
)

assert ok, str(extra)

dvs.remove_vlan_member("200", "PortChannel0005")
# check that the FDB entry was inserted into ASIC DB
assert how_many_entries_exist(dvs.adb, "ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY") == 0, "The MCLAG static should not be present in ASIC"

ok, extra = dvs.is_fdb_entry_exists(dvs.adb, "ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY",
[("mac", "3C:85:99:5E:00:01"), ("bvid", str(dvs.getVlanOid("200")))],
[("SAI_FDB_ENTRY_ATTR_TYPE", "SAI_FDB_ENTRY_TYPE_STATIC")]
)

assert ok == False, str(extra)

dvs.create_vlan_member("200", "PortChannel0005")
# check that the FDB entry was inserted into ASIC DB
assert how_many_entries_exist(dvs.adb, "ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY") == 1, "The MCLAG static fdb entry not inserted to ASIC"

ok, extra = dvs.is_fdb_entry_exists(dvs.adb, "ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY",
[("mac", "3C:85:99:5E:00:01"), ("bvid", str(dvs.getVlanOid("200")))],
[("SAI_FDB_ENTRY_ATTR_TYPE", "SAI_FDB_ENTRY_TYPE_STATIC")]
)
assert ok, str(extra)

delete_entry_pst(
dvs.pdb,
"MCLAG_FDB_TABLE", "Vlan200:3C:85:99:5E:00:01",
)


# Test-13 Remote Static MAC Add
# add static mac on vlan 200, portchannel5
# remove portchannel5 from vlan 200
# move mac from portchannel5 to portchannel6
# delete mac from portchannel6
# add portchannel5 to vlan 200
# verify whether static mac is configured on portchannel5

@pytest.mark.dev_sanity
def test_mclagFdb_remote_static_mac_use_cases(dvs, testlog):
dvs.setup_db()

create_entry_pst(
dvs.pdb,
"MCLAG_FDB_TABLE", "Vlan200:3C:85:99:5E:00:01",
[
("port", "PortChannel0005"),
("type", "static"),
]
)

# check that the FDB entry was inserted into ASIC DB
assert how_many_entries_exist(dvs.adb, "ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY") == 1, "The MCLAG static fdb entry not inserted to ASIC"

ok, extra = dvs.is_fdb_entry_exists(dvs.adb, "ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY",
[("mac", "3C:85:99:5E:00:01"), ("bvid", str(dvs.getVlanOid("200")))],
[("SAI_FDB_ENTRY_ATTR_TYPE", "SAI_FDB_ENTRY_TYPE_STATIC")]
)

assert ok, str(extra)

dvs.remove_vlan_member("200", "PortChannel0005")
# check that the FDB entry was inserted into ASIC DB
assert how_many_entries_exist(dvs.adb, "ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY") == 0, "The MCLAG static should not be present in ASIC"

ok, extra = dvs.is_fdb_entry_exists(dvs.adb, "ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY",
[("mac", "3C:85:99:5E:00:01"), ("bvid", str(dvs.getVlanOid("200")))],
[("SAI_FDB_ENTRY_ATTR_TYPE", "SAI_FDB_ENTRY_TYPE_STATIC")]
)
assert ok == False, str(extra)

#Move MAC to PortChannel0008 on Local PortChannel0006
create_entry_pst(
dvs.pdb,
"MCLAG_FDB_TABLE", "Vlan200:3C:85:99:5E:00:01",
[
("port", "PortChannel0006"),
("type", "static"),
]
)
# check that the FDB entry was inserted into ASIC DB
assert how_many_entries_exist(dvs.adb, "ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY") == 1, "The fdb entry inserted to ASIC"

ok, extra = dvs.is_fdb_entry_exists(dvs.adb, "ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY",
[("mac", "3C:85:99:5E:00:01"), ("bvid", str(dvs.getVlanOid("200")))],
[("SAI_FDB_ENTRY_ATTR_TYPE", "SAI_FDB_ENTRY_TYPE_STATIC")]
)

assert ok == True, str(extra)

delete_entry_pst(
dvs.pdb,
"MCLAG_FDB_TABLE", "Vlan200:3C:85:99:5E:00:01",
)

time.sleep(2)

# check that the FDB entry was inserted into ASIC DB
assert how_many_entries_exist(dvs.adb, "ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY") == 0, "The fdb entry flushed"

ok, extra = dvs.is_fdb_entry_exists(dvs.adb, "ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY",
[("mac", "3C:85:99:5E:00:01"), ("bvid", str(dvs.getVlanOid("200")))],
[("SAI_FDB_ENTRY_ATTR_TYPE", "SAI_FDB_ENTRY_TYPE_DYNAMIC")]
)

assert ok == False, str(extra)

dvs.create_vlan_member("200", "PortChannel0005")
# check that the FDB entry was inserted into ASIC DB
assert how_many_entries_exist(dvs.adb, "ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY") == 0, "The MCLAG static should not be present in ASIC"

ok, extra = dvs.is_fdb_entry_exists(dvs.adb, "ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY",
[("mac", "3C:85:99:5E:00:01"), ("bvid", str(dvs.getVlanOid("200")))],
[("SAI_FDB_ENTRY_ATTR_TYPE", "SAI_FDB_ENTRY_TYPE_STATIC")]
)

assert ok == False, str(extra)

time.sleep(2)
# check that the FDB entry was deleted from ASIC DB
assert how_many_entries_exist(dvs.adb, "ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY") == 0, "The MCLAG static fdb entry not deleted"
delete_entry_pst(
dvs.pdb,
"MCLAG_FDB_TABLE", "Vlan200:3C:85:99:5E:00:01",
)

# Test-14 Remote Static MAC Add
# add static mac on vlan 200, portchannel5
# remove portchannel5 from vlan 200
# move mac from portchannel5 to portchannel6
# move mac from portchannel6 to portchannel5 check for entry removed
# flush fdb entry
# add portchannel5 to vlan 200
# verify whether static mac is not configured on portchannel5

@pytest.mark.dev_sanity
def test_mclagFdb_remote_static_mac_use_cases_2(dvs, testlog):
dvs.setup_db()

create_entry_pst(
dvs.pdb,
"MCLAG_FDB_TABLE", "Vlan200:3C:85:99:5E:00:01",
[
("port", "PortChannel0005"),
("type", "static"),
]
)

# check that the FDB entry was inserted into ASIC DB
assert how_many_entries_exist(dvs.adb, "ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY") == 1, "The MCLAG static fdb entry not inserted to ASIC"

ok, extra = dvs.is_fdb_entry_exists(dvs.adb, "ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY",
[("mac", "3C:85:99:5E:00:01"), ("bvid", str(dvs.getVlanOid("200")))],
[("SAI_FDB_ENTRY_ATTR_TYPE", "SAI_FDB_ENTRY_TYPE_STATIC")]
)

assert ok, str(extra)

dvs.remove_vlan_member("200", "PortChannel0005")
time.sleep(2)
# check that the FDB entry was inserted into ASIC DB
assert how_many_entries_exist(dvs.adb, "ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY") == 0, "The MCLAG static should not be present in ASIC"

ok, extra = dvs.is_fdb_entry_exists(dvs.adb, "ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY",
[("mac", "3C:85:99:5E:00:01"), ("bvid", str(dvs.getVlanOid("200")))],
[("SAI_FDB_ENTRY_ATTR_TYPE", "SAI_FDB_ENTRY_TYPE_STATIC")]
)
assert ok == False, str(extra)

#Move MAC to PortChannel0008 on Local PortChannel0006
create_entry_pst(
dvs.pdb,
"MCLAG_FDB_TABLE", "Vlan200:3C:85:99:5E:00:01",
[
("port", "PortChannel0006"),
("type", "static"),
]
)
time.sleep(2)
# check that the FDB entry was inserted into ASIC DB
assert how_many_entries_exist(dvs.adb, "ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY") == 1, "The fdb entry inserted to ASIC"

ok, extra = dvs.is_fdb_entry_exists(dvs.adb, "ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY",
[("mac", "3C:85:99:5E:00:01"), ("bvid", str(dvs.getVlanOid("200")))],
[("SAI_FDB_ENTRY_ATTR_TYPE", "SAI_FDB_ENTRY_TYPE_STATIC")]
)

assert ok == True, str(extra)

#Move MAC to PortChannel0006 on Local PortChannel0005
create_entry_pst(
dvs.pdb,
"MCLAG_FDB_TABLE", "Vlan200:3C:85:99:5E:00:01",
[
("port", "PortChannel0005"),
("type", "static"),
]
)

time.sleep(2)
# check that the FDB entry was not inserted into ASIC DB
assert how_many_entries_exist(dvs.adb, "ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY") == 0, "The fdb entry should not be inserted to ASIC"

ok, extra = dvs.is_fdb_entry_exists(dvs.adb, "ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY",
[("mac", "3C:85:99:5E:00:01"), ("bvid", str(dvs.getVlanOid("200")))],
[("SAI_FDB_ENTRY_ATTR_TYPE", "SAI_FDB_ENTRY_TYPE_STATIC")]
)

assert ok == False, str(extra)


delete_entry_pst(
dvs.pdb,
"MCLAG_FDB_TABLE", "Vlan200:3C:85:99:5E:00:01",
)

time.sleep(2)

# check that the FDB entry was inserted into ASIC DB
assert how_many_entries_exist(dvs.adb, "ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY") == 0, "The fdb entry flushed"

ok, extra = dvs.is_fdb_entry_exists(dvs.adb, "ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY",
[("mac", "3C:85:99:5E:00:01"), ("bvid", str(dvs.getVlanOid("200")))],
[("SAI_FDB_ENTRY_ATTR_TYPE", "SAI_FDB_ENTRY_TYPE_DYNAMIC")]
)

assert ok == False, str(extra)

dvs.create_vlan_member("200", "PortChannel0005")
# check that the FDB entry was inserted into ASIC DB
time.sleep(2)
assert how_many_entries_exist(dvs.adb, "ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY") == 0, "The MCLAG static should not be present in ASIC"

ok, extra = dvs.is_fdb_entry_exists(dvs.adb, "ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY",
[("mac", "3C:85:99:5E:00:01"), ("bvid", str(dvs.getVlanOid("200")))],
[("SAI_FDB_ENTRY_ATTR_TYPE", "SAI_FDB_ENTRY_TYPE_STATIC")]
)

assert ok == False, str(extra)

time.sleep(2)
# check that the FDB entry was deleted from ASIC DB
assert how_many_entries_exist(dvs.adb, "ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY") == 0, "The MCLAG static fdb entry not deleted"
delete_entry_pst(
dvs.pdb,
"MCLAG_FDB_TABLE", "Vlan200:3C:85:99:5E:00:01",
)


# Test-15 Verify cleanup of the basic config.

@pytest.mark.dev_sanity
def test_mclagFdb_basic_config_del(dvs, testlog):
Expand Down