Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
JunhongMao committed Oct 4, 2023
2 parents 867a6d1 + 4f26a4d commit 185bfef
Show file tree
Hide file tree
Showing 9 changed files with 152 additions and 7 deletions.
24 changes: 24 additions & 0 deletions doc/Command-Reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,7 @@ The same syntax applies to all subgroups of `show` which themselves contain subc
Commands:
counters Show interface counters
description Show interface status, protocol and...
fec Show interface fec information
link-training Show interface link-training information
naming_mode Show interface naming_mode status
neighbor Show neighbor related information
Expand Down Expand Up @@ -4450,6 +4451,29 @@ This command displays the key fields of the interfaces such as Operational Statu
Ethernet4 down up hundredGigE1/2 T0-2:hundredGigE1/30
```

**show interfaces fec status (Versions >= 202311)**

This command is to display the FEC status of the selected interfaces. If **interface_name** is not specicied, this command shows the FEC status of all interfaces.

- Usage:
```
show interfaces fec status [<interface_name>]
```

- Example:
```
admin@sonic:~$ show interfaces fec status
Interface FEC Oper FEC Admin
----------- ---------- -----------
Ethernet0 N/A rs
Ethernet32 N/A rs
Ethernet36 N/A N/A
Ethernet112 N/A rs
Ethernet116 N/A rs
Ethernet120 N/A rs
Ethernet124 rs auto
```

**show interfaces link-training (Versions >= 202211)**

This command is to display the link-training status of the selected interfaces. If **interface_name** is not specicied, this command shows the link-training status of all interfaces.
Expand Down
60 changes: 60 additions & 0 deletions scripts/intfutil
Original file line number Diff line number Diff line change
Expand Up @@ -806,6 +806,63 @@ class IntfLinkTrainingStatus(object):
appl_db_port_status_get(self.db, key, PORT_ADMIN_STATUS)))
return table

# ========================== FEC logic ==========================
header_fec = ['Interface', 'FEC Oper', 'FEC Admin']

class IntfFecStatus(object):

def __init__(self, intf_name, namespace_option, display_option):
self.db = None
self.config_db = None
self.table = []
self.multi_asic = multi_asic_util.MultiAsic(
display_option, namespace_option)

if intf_name is not None and intf_name == SUB_PORT:
self.intf_name = None
else:
self.intf_name = intf_name

def display_fec_status(self):
self.get_intf_fec_status()
# Sorting and tabulating the result table.
sorted_table = natsorted(self.table)
print(tabulate(sorted_table, header_fec, tablefmt="simple", stralign='right'))

@multi_asic_util.run_on_multi_asic
def get_intf_fec_status(self):
self.front_panel_ports_list = get_frontpanel_port_list(self.config_db)
self.appl_db_keys = appl_db_keys_get(self.db, self.front_panel_ports_list, self.intf_name)
if self.appl_db_keys:
self.table += self.generate_fec_status()

def generate_fec_status(self):
"""
Generate FEC output
"""

i = {}
table = []
key = []

#
# Iterate through all the keys and append port's associated state to
# the result table.
#
for i in self.appl_db_keys:
key = re.split(':', i, maxsplit=1)[-1].strip()
if key in self.front_panel_ports_list:
if self.multi_asic.skip_display(constants.PORT_OBJ, key):
continue
admin_fec = appl_db_port_status_get(self.db, key, PORT_FEC)
oper_fec = self.db.get(self.db.STATE_DB, PORT_STATE_TABLE_PREFIX + key, PORT_FEC)
oper_status = self.db.get(self.db.APPL_DB, PORT_STATUS_TABLE_PREFIX + key, PORT_OPER_STATUS)
if oper_status != "up" or oper_fec is None:
oper_fec= "N/A"
oper_status = self.db.get(self.db.APPL_DB, PORT_STATUS_TABLE_PREFIX + key, PORT_OPER_STATUS)
table.append((key, oper_fec, admin_fec))
return table

def main():
parser = argparse.ArgumentParser(description='Display Interface information',
formatter_class=argparse.RawTextHelpFormatter)
Expand All @@ -829,6 +886,9 @@ def main():
elif args.command == "link_training":
interface_lt_status = IntfLinkTrainingStatus(args.interface, args.namespace, args.display)
interface_lt_status.display_link_training_status()
elif args.command == "fec":
interface_fec_status = IntfFecStatus(args.interface, args.namespace, args.display)
interface_fec_status.display_fec_status()

sys.exit(0)

Expand Down
34 changes: 33 additions & 1 deletion show/interfaces/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -764,7 +764,39 @@ def link_training_status(interfacename, namespace, display, verbose):
cmd += ['-n', str(namespace)]

clicommon.run_command(cmd, display_cmd=verbose)
#
# fec group (show interfaces fec ...)
#
@interfaces.group(name='fec', cls=clicommon.AliasedGroup)
def fec():
"""Show interface fec information"""
pass


# 'fec status' subcommand ("show interfaces fec status")
@fec.command(name='status')
@click.argument('interfacename', required=False)
@multi_asic_util.multi_asic_click_options
@click.option('--verbose', is_flag=True, help="Enable verbose output")
def fec_status(interfacename, namespace, display, verbose):
"""Show interface fec status"""

ctx = click.get_current_context()

cmd = ['intfutil', '-c', 'fec']

#ignore the display option when interface name is passed
if interfacename is not None:
interfacename = try_convert_interfacename_from_alias(ctx, interfacename)

cmd += ['-i', str(interfacename)]
else:
cmd += ['-d', str(display)]

if namespace is not None:
cmd += ['-n', str(namespace)]

clicommon.run_command(cmd, display_cmd=verbose)

#
# switchport group (show interfaces switchport ...)
Expand Down Expand Up @@ -830,4 +862,4 @@ def tablelize(keys):
return table

header = ['Interface', 'Mode']
click.echo(tabulate(tablelize(keys), header,tablefmt="simple", stralign='left'))
click.echo(tabulate(tablelize(keys), header,tablefmt="simple", stralign='left'))
2 changes: 1 addition & 1 deletion tests/config_an_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ def test_config_fec(self, ctx):
assert "fec fc is not in ['rs', 'none', 'test']" in result.output
# Negative case: set a fec mode which is not default on an interface without supported_fecs
result = self.basic_check("fec", ["Ethernet4", "test"], ctx, operator.ne)
assert "fec test is not in ['rs', 'fc', 'none']" in result.output
assert "fec test is not in ['rs', 'fc', 'none', 'auto']" in result.output
# Negative case: set a fec mode on a port where setting fec is not supported
result = self.basic_check("fec", ["Ethernet112", "test"], ctx, operator.ne)
assert "Setting fec is not supported" in result.output
Expand Down
24 changes: 23 additions & 1 deletion tests/intfutil_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
Ethernet112 93,94,95,96 40G 9100 rs etp29 PortChannel0001 up up N/A off
Ethernet116 89,90,91,92 40G 9100 rs etp30 PortChannel0002 up up N/A off
Ethernet120 101,102,103,104 40G 9100 rs etp31 PortChannel0003 up up N/A off
Ethernet124 97,98,99,100 40G 9100 rs etp32 PortChannel0004 up up N/A off
Ethernet124 97,98,99,100 40G 9100 auto etp32 PortChannel0004 up up N/A off
PortChannel0001 N/A 40G 9100 N/A N/A routed down up N/A N/A
PortChannel0002 N/A 40G 9100 N/A N/A routed up up N/A N/A
PortChannel0003 N/A 40G 9100 N/A N/A routed up up N/A N/A
Expand Down Expand Up @@ -112,6 +112,21 @@
Ethernet124 N/A N/A up up
"""

show_interface_fec_status_output = """\
Interface FEC Oper FEC Admin
----------- ---------- -----------
Ethernet0 N/A rs
Ethernet16 N/A N/A
Ethernet24 N/A N/A
Ethernet28 N/A N/A
Ethernet32 N/A rs
Ethernet36 N/A N/A
Ethernet112 N/A rs
Ethernet116 N/A rs
Ethernet120 N/A rs
Ethernet124 rs auto
"""

class TestIntfutil(TestCase):
@classmethod
def setup_class(cls):
Expand Down Expand Up @@ -338,6 +353,13 @@ def test_show_interfaces_link_training_status(self):
assert result.exit_code == 0
assert result.output == show_interface_link_training_status_output

def test_show_interfaces_fec_status(self):
result = self.runner.invoke(show.cli.commands["interfaces"].commands["fec"].commands["status"], [])
print(result.exit_code)
print(result.output)
assert result.exit_code == 0
assert result.output == show_interface_fec_status_output

@classmethod
def teardown_class(cls):
print("TEARDOWN")
Expand Down
2 changes: 1 addition & 1 deletion tests/mock_tables/appl_db.json
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@
"pfc_asym": "off",
"mtu": "9100",
"tpid": "0x8100",
"fec": "rs",
"fec": "auto",
"admin_status": "up"
},
"PORT_TABLE:Ethernet200": {
Expand Down
3 changes: 2 additions & 1 deletion tests/mock_tables/config_db.json
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,8 @@
"tpid": "0x8100",
"mode": "routed",
"pfc_asym": "off",
"speed": "40000"
"speed": "40000",
"fec" : "auto"
},
"VLAN_SUB_INTERFACE|Ethernet0.10": {
"admin_status": "up"
Expand Down
8 changes: 7 additions & 1 deletion tests/mock_tables/state_db.json
Original file line number Diff line number Diff line change
Expand Up @@ -1356,7 +1356,8 @@
"speed" : "100000",
"supported_speeds": "10000,25000,40000,100000",
"supported_fecs": "rs,none,test",
"link_training_status": "not_trained"
"link_training_status": "not_trained",
"fec": "rs"
},
"PORT_TABLE|Ethernet32": {
"link_training_status": "trained"
Expand All @@ -1366,6 +1367,11 @@
"supported_fecs": "N/A",
"link_training_status": "off"
},
"PORT_TABLE|Ethernet124": {
"speed": "40000",
"supported_fecs": "rs,none,fc,auto",
"fec": "rs"
},
"PCIE_DEVICE|00:01.0": {
"correctable|BadDLLP": "0",
"correctable|BadTLP": "0",
Expand Down
2 changes: 1 addition & 1 deletion utilities_common/constants.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#All the constant used in sonic-utilities

DEFAULT_NAMESPACE = ''
DEFAULT_SUPPORTED_FECS_LIST = [ 'rs', 'fc', 'none']
DEFAULT_SUPPORTED_FECS_LIST = [ 'rs', 'fc', 'none', 'auto']
DISPLAY_ALL = 'all'
DISPLAY_EXTERNAL = 'frontend'
BGP_NEIGH_OBJ = 'BGP_NEIGH'
Expand Down

0 comments on commit 185bfef

Please sign in to comment.