Skip to content

Commit

Permalink
Add port flap count and last flap timestamp
Browse files Browse the repository at this point in the history
Signed-off-by: Prince George <prgeor@microsoft.com>
  • Loading branch information
prgeor committed Feb 26, 2024
1 parent 41330ab commit fe41dd4
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 2 deletions.
1 change: 1 addition & 0 deletions orchagent/port.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ class Port
uint32_t m_nat_zone_id = 0;
uint32_t m_vnid = VNID_NONE;
uint32_t m_fdb_count = 0;
uint32_t m_flap_count = 0;
uint32_t m_up_member_count = 0;
uint32_t m_maximum_headroom = 0;
std::set<uint32_t> m_adv_speeds;
Expand Down
56 changes: 54 additions & 2 deletions orchagent/portsorch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3074,6 +3074,38 @@ bool PortsOrch::removeVlanHostIntf(Port vl)
return true;
}

void PortsOrch::updateDbPortFlapCount(Port& port, sai_port_oper_status_t pstatus)
{
SWSS_LOG_ENTER();

++port.m_flap_count;
vector<FieldValueTuple> tuples;
FieldValueTuple tuple("flap_count", std::to_string(port.m_flap_count));
tuples.push_back(tuple);
m_portTable->set(port.m_alias, tuples);

if (pstatus == SAI_PORT_OPER_STATUS_DOWN)
{
vector<FieldValueTuple> tuples;
auto now = std::chrono::system_clock::now();
std::time_t now_c = std::chrono::system_clock::to_time_t(now);
FieldValueTuple tuple("last_down_time", std::ctime(&now_c));
tuples.push_back(tuple);
m_portTable->set(port.m_alias, tuples);
}

if (pstatus == SAI_PORT_OPER_STATUS_UP)
{
vector<FieldValueTuple> tuples;
auto now = std::chrono::system_clock::now();
std::time_t now_c = std::chrono::system_clock::to_time_t(now);
FieldValueTuple tuple("last_up_time", std::ctime(&now_c));
tuples.push_back(tuple);
m_portTable->set(port.m_alias, tuples);
}
}


void PortsOrch::updateDbPortOperStatus(const Port& port, sai_port_oper_status_t status) const
{
SWSS_LOG_ENTER();
Expand Down Expand Up @@ -5282,7 +5314,7 @@ bool PortsOrch::initializePort(Port &port)
/* Check warm start states */
vector<FieldValueTuple> tuples;
bool exist = m_portTable->get(port.m_alias, tuples);
string operStatus;
string operStatus, flapCount = "0";
if (exist)
{
for (auto i : tuples)
Expand All @@ -5291,9 +5323,14 @@ bool PortsOrch::initializePort(Port &port)
{
operStatus = fvValue(i);
}

if (fvField(i) == "flap_count")
{
flapCount = fvValue(i);
}
}
}
SWSS_LOG_DEBUG("initializePort %s with oper %s", port.m_alias.c_str(), operStatus.c_str());
SWSS_LOG_NOTICE("Port %s with oper %s flap_count=%s", port.m_alias.c_str(), operStatus.c_str(), flapCount.c_str());

/**
* Create database port oper status as DOWN if attr missing
Expand All @@ -5314,6 +5351,20 @@ bool PortsOrch::initializePort(Port &port)
port.m_oper_status = SAI_PORT_OPER_STATUS_DOWN;
}

// initalize port flap count
if (!flapCount.empty())
{
try
{
port.m_flap_count = to_uint<std::uint32_t>(flapCount);
}
catch (const std::exception &e)
{
SWSS_LOG_ERROR("Failed to get port (%s) flap_count: %s", port.m_alias.c_str(), e.what());
}
m_portTable->hset(port.m_alias, "flap_count", flapCount);
}

/* initialize port admin status */
if (!getPortAdminStatus(port.m_port_id, port.m_admin_state_up))
{
Expand Down Expand Up @@ -7545,6 +7596,7 @@ void PortsOrch::updatePortOperStatus(Port &port, sai_port_oper_status_t status)
if (port.m_type == Port::PHY)
{
updateDbPortOperStatus(port, status);
updateDbPortFlapCount(port, status);
updateGearboxPortOperStatus(port);

/* Refresh the port states and reschedule the poller tasks */
Expand Down
2 changes: 2 additions & 0 deletions orchagent/portsorch.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,8 @@ class PortsOrch : public Orch, public Subject

bool setHostIntfsOperStatus(const Port& port, bool up) const;
void updateDbPortOperStatus(const Port& port, sai_port_oper_status_t status) const;
void updateDbPortFlapCount(Port& port, sai_port_oper_status_t pstatus);


bool createVlanHostIntf(Port& vl, string hostif_name);
bool removeVlanHostIntf(Port vl);
Expand Down
47 changes: 47 additions & 0 deletions tests/test_port.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,53 @@ def test_PortMtu(self, dvs, testlog):
if fv[0] == "mtu":
assert fv[1] == "9100"

def test_PortFlapCount(self, dvs, testlog):
def get_port_flapcount(dvs):
db = swsscommon.DBConnector(0, dvs.redis_sock, 0)
tbl = swsscommon.Table(db, "PORT_TABLE")
(status, fvs) = tbl.get("Ethernet0")
assert status == True
fcount = 0

for v in fvs:
if v[0] == "flap_count":
fcount = v[1]
break
return fcount

def port_change_admin_status(dvs, op_status):
dvs.servers[0].runcmd("ip link set {} dev eth0".format(op_status)) == 0
time.sleep(1)

db = swsscommon.DBConnector(0, dvs.redis_sock, 0)
tbl = swsscommon.Table(db, "PORT_TABLE")
(status, fvs) = tbl.get("Ethernet0")
assert status == True

oper_status = "unknown"
for v in fvs:
if v[0] == "oper_status":
oper_status = v[1]
break

assert oper_status == op_status

dvs.port_admin_set("Ethernet0", "up")
dvs.interface_ip_add("Ethernet0", "10.0.0.0/31")
dvs.port_admin_set("Ethernet4", "up")
dvs.interface_ip_add("Ethernet4", "10.0.0.2/31")
#Init the flap_count = 0
fvs = swsscommon.FieldValuePairs([("flap_count", "0")])

port_change_admin_status(dvs, "down")
assert 1 == get_port_flapcount(dvs)
port_change_admin_status(dvs, "up")
assert 2 == get_port_flapcount(dvs)
port_change_admin_status(dvs, "down")
assert 3 == get_port_flapcount(dvs)
port_change_admin_status(dvs, "up")
assert 4 == get_port_flapcount(dvs)

def test_PortNotification(self, dvs, testlog):
dvs.port_admin_set("Ethernet0", "up")
dvs.interface_ip_add("Ethernet0", "10.0.0.0/31")
Expand Down

0 comments on commit fe41dd4

Please sign in to comment.