Skip to content

Commit

Permalink
[sonic-utilities] CLI support for port auto negotiation (#1568)
Browse files Browse the repository at this point in the history
#### What I did

1. Add CLI support for port auto negotiation feature.
2. Add db_migrator change for auto negotiation feature
2. Add unit test cases for all changes

#### How I did it

1. Add new subcommands to "config interface" command group to allow user configuring port auto negotiation
2. Add new subcommands to "show interfaces" command group to allow user show auto negotiation status
3. In db_migrator.py, change auto negotiation related DB field to latest one
  • Loading branch information
Junchao-Mellanox committed May 7, 2021
1 parent a71ff02 commit 8c2980a
Show file tree
Hide file tree
Showing 14 changed files with 735 additions and 9 deletions.
120 changes: 120 additions & 0 deletions config/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -3014,6 +3014,126 @@ def speed(ctx, interface_name, interface_speed, verbose):
command += " -vv"
clicommon.run_command(command, display_cmd=verbose)

#
# 'autoneg' subcommand
#

@interface.command()
@click.pass_context
@click.argument('interface_name', metavar='<interface_name>', required=True)
@click.argument('mode', metavar='<mode>', required=True, type=click.Choice(["enabled", "disabled"]))
@click.option('-v', '--verbose', is_flag=True, help="Enable verbose output")
def autoneg(ctx, interface_name, mode, verbose):
"""Set interface auto negotiation mode"""
# Get the config_db connector
config_db = ctx.obj['config_db']

if clicommon.get_interface_naming_mode() == "alias":
interface_name = interface_alias_to_name(config_db, interface_name)
if interface_name is None:
ctx.fail("'interface_name' is None!")

log.log_info("'interface autoneg {} {}' executing...".format(interface_name, mode))

if ctx.obj['namespace'] is DEFAULT_NAMESPACE:
command = "portconfig -p {} -an {}".format(interface_name, mode)
else:
command = "portconfig -p {} -an {} -n {}".format(interface_name, mode, ctx.obj['namespace'])

if verbose:
command += " -vv"
clicommon.run_command(command, display_cmd=verbose)

#
# 'adv-speeds' subcommand
#

@interface.command()
@click.pass_context
@click.argument('interface_name', metavar='<interface_name>', required=True)
@click.argument('speed_list', metavar='<speed_list>', required=True)
@click.option('-v', '--verbose', is_flag=True, help="Enable verbose output")
def advertised_speeds(ctx, interface_name, speed_list, verbose):
"""Set interface advertised speeds"""
# Get the config_db connector
config_db = ctx.obj['config_db']

if clicommon.get_interface_naming_mode() == "alias":
interface_name = interface_alias_to_name(config_db, interface_name)
if interface_name is None:
ctx.fail("'interface_name' is None!")

log.log_info("'interface advertised_speeds {} {}' executing...".format(interface_name, speed_list))

if ctx.obj['namespace'] is DEFAULT_NAMESPACE:
command = "portconfig -p {} -S {}".format(interface_name, speed_list)
else:
command = "portconfig -p {} -S {} -n {}".format(interface_name, speed_list, ctx.obj['namespace'])

if verbose:
command += " -vv"
clicommon.run_command(command, display_cmd=verbose)

#
# 'interface-type' subcommand
#

@interface.command(name='type')
@click.pass_context
@click.argument('interface_name', metavar='<interface_name>', required=True)
@click.argument('interface_type_value', metavar='<interface_type_value>', required=True)
@click.option('-v', '--verbose', is_flag=True, help="Enable verbose output")
def interface_type(ctx, interface_name, interface_type_value, verbose):
"""Set interface type"""
# Get the config_db connector
config_db = ctx.obj['config_db']

if clicommon.get_interface_naming_mode() == "alias":
interface_name = interface_alias_to_name(config_db, interface_name)
if interface_name is None:
ctx.fail("'interface_name' is None!")

log.log_info("'interface interface_type {} {}' executing...".format(interface_name, interface_type_value))

if ctx.obj['namespace'] is DEFAULT_NAMESPACE:
command = "portconfig -p {} -t {}".format(interface_name, interface_type_value)
else:
command = "portconfig -p {} -t {} -n {}".format(interface_name, interface_type_value, ctx.obj['namespace'])

if verbose:
command += " -vv"
clicommon.run_command(command, display_cmd=verbose)

#
# 'advertised-interface-types' subcommand
#

@interface.command()
@click.pass_context
@click.argument('interface_name', metavar='<interface_name>', required=True)
@click.argument('interface_type_list', metavar='<interface_type_list>', required=True)
@click.option('-v', '--verbose', is_flag=True, help="Enable verbose output")
def advertised_types(ctx, interface_name, interface_type_list, verbose):
"""Set interface advertised types"""
# Get the config_db connector
config_db = ctx.obj['config_db']

if clicommon.get_interface_naming_mode() == "alias":
interface_name = interface_alias_to_name(config_db, interface_name)
if interface_name is None:
ctx.fail("'interface_name' is None!")

log.log_info("'interface advertised_interface_types {} {}' executing...".format(interface_name, interface_type_list))

if ctx.obj['namespace'] is DEFAULT_NAMESPACE:
command = "portconfig -p {} -T {}".format(interface_name, interface_type_list)
else:
command = "portconfig -p {} -T {} -n {}".format(interface_name, interface_type_list, ctx.obj['namespace'])

if verbose:
command += " -vv"
clicommon.run_command(command, display_cmd=verbose)

#
# 'breakout' subcommand
#
Expand Down
127 changes: 127 additions & 0 deletions doc/Command-Reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -3064,6 +3064,7 @@ Subsequent pages explain each of these commands in detail.
-?, -h, --help Show this message and exit.
Commands:
autoneg Show interface autoneg information
breakout Show Breakout Mode information by interfaces
counters Show interface counters
description Show interface status, protocol and...
Expand All @@ -3074,6 +3075,30 @@ Subsequent pages explain each of these commands in detail.
transceiver Show SFP Transceiver information
```

**show interfaces autoneg**

This show command displays the port auto negotiation status for all interfaces i.e. interface name, auto negotiation mode, speed, advertised speeds, interface type, advertised interface types, operational status, admin status. For a single interface, provide the interface name with the sub-command.

- Usage:
```
show interfaces autoneg status
show interfaces autoneg status <interface_name>
```

- Example:
```
admin@sonic:~$ show interfaces autoneg status
Interface Auto-Neg Mode Speed Adv Speeds Type Adv Types Oper Admin
----------- --------------- ------- ------------ ------ ----------- ------ -------
Ethernet0 enabled 25G 10G,25G CR CR,CR4 up up
Ethernet4 disabled 100G all CR4 all up up
admin@sonic:~$ show interfaces autoneg status Ethernet8
Interface Auto-Neg Mode Speed Adv Speeds Type Adv Types Oper Admin
----------- --------------- ------- ------------ ------ ----------- ------ -------
Ethernet8 disabled 100G N/A CR4 N/A up up
```

**show interfaces breakout**

This show command displays the port capability for all interfaces i.e. index, lanes, default_brkout_mode, breakout_modes(i.e. all the available breakout modes) and brkout_mode (i.e. current breakout mode). To display current breakout mode, "current-mode" subcommand can be used.For a single interface, provide the interface name with the sub-command.
Expand Down Expand Up @@ -3380,6 +3405,10 @@ This sub-section explains the following list of configuration on the interfaces.
4) speed - to set the interface speed
5) startup - to bring up the administratively shutdown interface
6) breakout - to set interface breakout mode
7) autoneg - to set interface auto negotiation mode
8) advertised-speeds - to set interface advertised speeds
9) advertised-types - to set interface advertised types
10) type - to set interface type

From 201904 release onwards, the “config interface” command syntax is changed and the format is as follows:

Expand Down Expand Up @@ -3714,6 +3743,104 @@ kindly use, double tab i.e. <tab><tab> to see the available breakout option cust

Go Back To [Beginning of the document](#) or [Beginning of this section](#interfaces)

**config interface autoneg <interface_name> (Versions >= 202106)**

This command is used to set port auto negotiation mode.

- Usage:
```
sudo config interface autoneg --help
Usage: config interface autoneg [OPTIONS] <interface_name> <mode>
Set interface auto negotiation mode
Options:
-v, --verbose Enable verbose output
-h, -?, --help Show this message and exit.
```

- Example:
```
admin@sonic:~$ sudo config interface autoneg Ethernet0 enabled
admin@sonic:~$ sudo config interface autoneg Ethernet0 disabled
```

Go Back To [Beginning of the document](#) or [Beginning of this section](#interfaces)

**config interface advertised-speeds <interface_name> (Versions >= 202106)**

This command is used to set port advertised speed.

- Usage:
```
sudo config interface advertised-speeds --help
Usage: config interface advertised-speeds [OPTIONS] <interface_name> <speed_list>
Set interface advertised speeds
Options:
-v, --verbose Enable verbose output
-h, -?, --help Show this message and exit.
```

- Example:
```
admin@sonic:~$ sudo config interface advertised-speeds Ethernet0 all
admin@sonic:~$ sudo config interface advertised-speeds Ethernet0 50000,100000
```

Go Back To [Beginning of the document](#) or [Beginning of this section](#interfaces)

**config interface advertised-types <interface_name> (Versions >= 202106)**

This command is used to set port advertised interface types.

- Usage:
```
sudo config interface advertised-types --help
Usage: config interface advertised-types [OPTIONS] <interface_name> <interface_type_list>
Set interface advertised types
Options:
-v, --verbose Enable verbose output
-h, -?, --help Show this message and exit.
```

- Example:
```
admin@sonic:~$ sudo config interface advertised-types Ethernet0 all
admin@sonic:~$ sudo config interface advertised-types Ethernet0 CR,CR4
```

Go Back To [Beginning of the document](#) or [Beginning of this section](#interfaces)

**config interface type <interface_name> (Versions >= 202106)**

This command is used to set port interface type.

- Usage:
```
sudo config interface type --help
Usage: config interface type [OPTIONS] <interface_name> <interface_type_value>
Set interface type
Options:
-v, --verbose Enable verbose output
-h, -?, --help Show this message and exit.
```

- Example:
```
admin@sonic:~$ sudo config interface type Ethernet0 CR4
```

Go Back To [Beginning of the document](#) or [Beginning of this section](#interfaces)

**config interface cable_length (Versions >= 202006)**

This command is used to configure the length of the cable connected to a port. The cable_length is in unit of meters and must be suffixed with "m".
Expand Down
22 changes: 21 additions & 1 deletion scripts/db_migrator.py
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,18 @@ def prepare_dynamic_buffer_for_warm_reboot(self, buffer_pools=None, buffer_profi

return True

def migrate_config_db_port_table_for_auto_neg(self):
table_name = 'PORT'
port_table = self.configDB.get_table(table_name)
for key, value in port_table.items():
if 'autoneg' in value:
if value['autoneg'] == '1':
self.configDB.set(self.configDB.CONFIG_DB, '{}|{}'.format(table_name, key), 'autoneg', 'on')
if 'speed' in value and 'adv_speeds' not in value:
self.configDB.set(self.configDB.CONFIG_DB, '{}|{}'.format(table_name, key), 'adv_speeds', value['speed'])
elif value['autoneg'] == '0':
self.configDB.set(self.configDB.CONFIG_DB, '{}|{}'.format(table_name, key), 'autoneg', 'off')

def version_unknown(self):
"""
version_unknown tracks all SONiC versions that doesn't have a version
Expand Down Expand Up @@ -470,10 +482,18 @@ def version_1_0_5(self):

def version_2_0_0(self):
"""
Current latest version. Nothing to do here.
Version 2_0_0.
"""
log.log_info('Handling version_2_0_0')
self.migrate_config_db_port_table_for_auto_neg()
self.set_version('version_2_0_1')
return 'version_2_0_1'

def version_2_0_1(self):
"""
Current latest version. Nothing to do here.
"""
log.log_info('Handling version_2_0_1')
return None

def get_version(self):
Expand Down
Loading

0 comments on commit 8c2980a

Please sign in to comment.