Skip to content

Commit

Permalink
Update netlink messages handler (#2233)
Browse files Browse the repository at this point in the history
- What I did
Ignore netlink DELLINK messages if port has master, this is applicable to the case where port was part of VLAN bridge or LAG.

- Why I did it
Netlink messages handler in portsyncd was ignoring all messages that had master.
Therefore we ignored messages on interfaces that belong to LAG (not only interfaces belong to bridge as intended).
The result was "netdev_oper_status" down in PORT_TABLE in state DB for port which is part of LAG although it is actually up.

- How I verified it
Check "netdev_oper_status" in PORT_TABLE in state DB for port which is part of LAG.
  • Loading branch information
liorghub authored May 25, 2022
1 parent 40316f7 commit 7fc0f73
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 4 deletions.
7 changes: 3 additions & 4 deletions portsyncd/linksync.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -205,10 +205,9 @@ void LinkSync::onMsg(int nlmsg_type, struct nl_object *obj)
return;
}

/* If netlink for this port has master, we ignore that for now
* This could be the case where the port was removed from VLAN bridge
*/
if (master)
/* Ignore DELLINK message if port has master, this is applicable to
* the case where port was part of VLAN bridge or LAG */
if (master && nlmsg_type == RTM_DELLINK)
{
return;
}
Expand Down
57 changes: 57 additions & 0 deletions tests/test_portchannel.py
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,63 @@ def test_Portchannel_tpid(self, dvs, testlog):
tbl._del("PortChannel0002")
time.sleep(1)

def test_portchannel_member_netdev_oper_status(self, dvs, testlog):
config_db = swsscommon.DBConnector(swsscommon.CONFIG_DB, dvs.redis_sock, 0)
state_db = swsscommon.DBConnector(swsscommon.STATE_DB, dvs.redis_sock, 0)
app_db = swsscommon.DBConnector(swsscommon.APPL_DB, dvs.redis_sock, 0)

# create port-channel
tbl = swsscommon.Table(config_db, "PORTCHANNEL")
fvs = swsscommon.FieldValuePairs([("admin_status", "up"),("mtu", "9100"),("oper_status", "up")])
tbl.set("PortChannel111", fvs)

# set port-channel oper status
tbl = swsscommon.ProducerStateTable(app_db, "LAG_TABLE")
fvs = swsscommon.FieldValuePairs([("admin_status", "up"),("mtu", "9100"),("oper_status", "up")])
tbl.set("PortChannel111", fvs)

# add members to port-channel
tbl = swsscommon.Table(config_db, "PORTCHANNEL_MEMBER")
fvs = swsscommon.FieldValuePairs([("NULL", "NULL")])
tbl.set("PortChannel111|Ethernet0", fvs)
tbl.set("PortChannel111|Ethernet4", fvs)

# wait for port-channel netdev creation
time.sleep(1)

# set netdev oper status
(exitcode, _) = dvs.runcmd("ip link set up dev Ethernet0")
assert exitcode == 0, "ip link set failed"

(exitcode, _) = dvs.runcmd("ip link set up dev Ethernet4")
assert exitcode == 0, "ip link set failed"

(exitcode, _) = dvs.runcmd("ip link set dev PortChannel111 carrier on")
assert exitcode == 0, "ip link set failed"

# verify port-channel members netdev oper status
tbl = swsscommon.Table(state_db, "PORT_TABLE")
status, fvs = tbl.get("Ethernet0")
assert status is True
fvs = dict(fvs)
assert fvs['netdev_oper_status'] == 'up'

status, fvs = tbl.get("Ethernet4")
assert status is True
fvs = dict(fvs)
assert fvs['netdev_oper_status'] == 'up'

# remove port-channel members
tbl = swsscommon.Table(config_db, "PORTCHANNEL_MEMBER")
tbl._del("PortChannel111|Ethernet0")
tbl._del("PortChannel111|Ethernet4")

# remove port-channel
tbl = swsscommon.Table(config_db, "PORTCHANNEL")
tbl._del("PortChannel111")

# wait for port-channel deletion
time.sleep(1)

# Add Dummy always-pass test at end as workaroud
# for issue when Flaky fail on final test it invokes module tear-down before retrying
Expand Down

0 comments on commit 7fc0f73

Please sign in to comment.