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

[fdb & vstest/mirror] Populate FdbEntry port_name in APPL_DB SET path #1827

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
24 changes: 11 additions & 13 deletions orchagent/fdborch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@ bool FdbOrch::storeFdbEntryState(const FdbUpdate& update)

if (!m_portsOrch->getPort(entry.bv_id, vlan))
{
SWSS_LOG_NOTICE("FdbOrch notification: Failed to locate \
vlan port from bv_id 0x%" PRIx64, entry.bv_id);
SWSS_LOG_NOTICE("FdbOrch notification: Failed to locate "
"vlan port from bv_id 0x%" PRIx64, entry.bv_id);
return false;
}

Expand Down Expand Up @@ -163,8 +163,8 @@ void FdbOrch::update(sai_fdb_event_t type,
update.type = "dynamic";
Port vlan;

SWSS_LOG_INFO("FDB event:%d, MAC: %s , BVID: 0x%" PRIx64 " , \
bridge port ID: 0x%" PRIx64 ".",
SWSS_LOG_INFO("FDB event:%d, MAC: %s , BVID: 0x%" PRIx64 " , "
"bridge port ID: 0x%" PRIx64 ".",
type, update.entry.mac.to_string().c_str(),
entry->bv_id, bridge_port_id);

Expand Down Expand Up @@ -362,8 +362,8 @@ void FdbOrch::update(sai_fdb_event_t type,
}
case SAI_FDB_EVENT_FLUSHED:

SWSS_LOG_INFO("FDB Flush event received: [ %s , 0x%" PRIx64 " ], \
bridge port ID: 0x%" PRIx64 ".",
SWSS_LOG_INFO("FDB Flush event received: [ %s , 0x%" PRIx64 " ], "
"bridge port ID: 0x%" PRIx64 ".",
update.entry.mac.to_string().c_str(), entry->bv_id,
bridge_port_id);

Expand All @@ -373,8 +373,8 @@ void FdbOrch::update(sai_fdb_event_t type,

if (!m_portsOrch->getPort(entry->bv_id, vlan))
{
SWSS_LOG_NOTICE("FdbOrch notification: Failed to locate vlan\
port from bv_id 0x%" PRIx64, entry->bv_id);
SWSS_LOG_NOTICE("FdbOrch notification: Failed to locate vlan "
"port from bv_id 0x%" PRIx64, entry->bv_id);
return;
}
vlanName = "Vlan" + to_string(vlan.m_vlan_info.vlan_id);
Expand Down Expand Up @@ -439,7 +439,6 @@ void FdbOrch::update(sai_fdb_event_t type,
SWSS_LOG_ERROR("Unsupported FDB Flush: [ %s , %s ] = { port: - }",
update.entry.mac.to_string().c_str(),
vlanName.c_str());

}
else
{
Expand Down Expand Up @@ -647,6 +646,7 @@ void FdbOrch::doTask(Consumer& consumer)
port = tunnel_orch->getTunnelPortName(remote_ip);
}

entry.port_name = port;

FdbData fdbData;
fdbData.bridge_port_id = SAI_NULL_OBJECT_ID;
Expand All @@ -666,7 +666,6 @@ void FdbOrch::doTask(Consumer& consumer)
it = consumer.m_toSync.erase(it);
else
it++;

}
else
{
Expand Down Expand Up @@ -881,8 +880,8 @@ void FdbOrch::notifyObserversFDBFlush(Port &port, sai_object_id_t& bvid)
if ((itr->first.port_name == port.m_alias) &&
(itr->first.bv_id == bvid))
{
SWSS_LOG_INFO("Adding MAC learnt on [ port:%s , bvid:0x%" PRIx64 "]\
to ARP flush", port.m_alias.c_str(), bvid);
SWSS_LOG_INFO("Adding MAC learnt on [ port:%s , bvid:0x%" PRIx64 "] "
"to ARP flush", port.m_alias.c_str(), bvid);
FdbEntry entry;
entry.mac = itr->first.mac;
entry.bv_id = itr->first.bv_id;
Expand Down Expand Up @@ -920,7 +919,6 @@ void FdbOrch::updatePortOperState(const PortOperStateUpdate& update)
}
notifyObserversFDBFlush(p, vlan.m_vlan_info.vlan_oid);
}

}
return;
}
Expand Down
1 change: 1 addition & 0 deletions orchagent/mirrororch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -576,6 +576,7 @@ bool MirrorOrch::getNeighborInfo(const string& name, MirrorEntry& session)
!m_neighOrch->getNeighborEntry(session.nexthopInfo.nexthop,
session.neighborInfo.neighbor, session.neighborInfo.mac)))
{
session.neighborInfo.mac = MacAddress();
return false;
}

Expand Down
74 changes: 70 additions & 4 deletions tests/test_mirror.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,15 @@ def setup_db(self, dvs):
self.cdb = swsscommon.DBConnector(4, dvs.redis_sock, 0)
self.sdb = swsscommon.DBConnector(6, dvs.redis_sock, 0)

def set_port_oper_status(self, dvs, port_name, status):
if port_name.startswith("Ethernet"):
srv_idx = int(port_name[len("Ethernet"):]) // 4
dvs.servers[srv_idx].runcmd("ip link set dev eth0 " + status)
elif port_name.startswith("PortChannel"):
dvs.runcmd("bash -c 'echo " + ("1" if status == "up" else "0") + \
" > /sys/class/net/" + port_name + "/carrier'")
time.sleep(1)

def set_interface_status(self, dvs, interface, admin_status):
if interface.startswith("PortChannel"):
tbl_name = "PORTCHANNEL"
Expand All @@ -26,11 +35,13 @@ def set_interface_status(self, dvs, interface, admin_status):
tbl.set(interface, fvs)
time.sleep(1)

# when using FRR, route cannot be inserted if the neighbor is not
# connected. thus it is mandatory to force the interface up manually
if interface.startswith("PortChannel"):
dvs.runcmd("bash -c 'echo " + ("1" if admin_status == "up" else "0") +\
" > /sys/class/net/" + interface + "/carrier'")
# when using FRR, route cannot be inserted if the neighbor is not
# connected. thus it is mandatory to force the interface up manually
self.set_port_oper_status(dvs, interface, admin_status)
elif interface.startswith("Ethernet"):
self.set_port_oper_status(dvs, interface, "down")
self.set_port_oper_status(dvs, interface, "up")

def add_ip_address(self, interface, ip):
if interface.startswith("PortChannel"):
Expand Down Expand Up @@ -239,6 +250,11 @@ def remove_fdb(self, vlan, mac):
tbl._del("Vlan" + vlan + ":" + mac)
time.sleep(1)

def flush_fdb(self, op, data):
ntf = swsscommon.NotificationProducer(self.adb, "FLUSHFDBREQUEST")
fvs = swsscommon.FieldValuePairs()
ntf.send(op, data, fvs)
time.sleep(1)

# Ignore testcase in Debian Jessie
# TODO: Remove this skip if Jessie support is no longer needed
Expand Down Expand Up @@ -328,6 +344,56 @@ def test_MirrorToVlanAddRemove(self, dvs, testlog):
else:
assert False

# test port oper status down that triggers fdb flush on port, which further triggers neighbor flush
self.set_port_oper_status(dvs, "Ethernet4", "down")
assert self.get_mirror_session_state(session)["status"] == "inactive"
tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_MIRROR_SESSION")
assert len(tbl.getKeys()) == 0
# Allow time for neighor flush to occur
time.sleep(1)

# restore port oper status up
self.set_port_oper_status(dvs, "Ethernet4", "up")

# restore fdb entry to ethernet 4
self.create_fdb("6", "66-66-66-66-66-66", "Ethernet4")
assert self.get_mirror_session_state(session)["status"] == "inactive"
tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_MIRROR_SESSION")
assert len(tbl.getKeys()) == 0

# restore neighbor to vlan 6
self.add_neighbor("Vlan6", "6.6.6.6", "66:66:66:66:66:66")
assert self.get_mirror_session_state(session)["status"] == "active"
tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_MIRROR_SESSION")
assert len(tbl.getKeys()) == 1

# test fdb flush all from appl db
self.flush_fdb("ALL", "ALL")
assert self.get_mirror_session_state(session)["status"] == "inactive"
tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_MIRROR_SESSION")
assert len(tbl.getKeys()) == 0

# restore fdb entry to ethernet 4
self.create_fdb("6", "66-66-66-66-66-66", "Ethernet4")
assert self.get_mirror_session_state(session)["status"] == "active"
tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_MIRROR_SESSION")
assert len(tbl.getKeys()) == 1

# test fdb flush port from appl db
self.flush_fdb("PORT", "Ethernet4")
assert self.get_mirror_session_state(session)["status"] == "inactive"
tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_MIRROR_SESSION")
assert len(tbl.getKeys()) == 0

# restore fdb entry to ethernet 4
self.create_fdb("6", "66-66-66-66-66-66", "Ethernet4")
assert self.get_mirror_session_state(session)["status"] == "active"
tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_MIRROR_SESSION")
assert len(tbl.getKeys()) == 1

# test fdb flush vlan from appl db, the corresponding flush event from asic db not yet handled
# test fdb flush {vlan, port} from appl db, the corresponding flush event from asic db not yet handled

# remove fdb entry
self.remove_fdb("6", "66-66-66-66-66-66")
assert self.get_mirror_session_state(session)["status"] == "inactive"
Expand Down