Skip to content

Commit 8c2980a

Browse files
[sonic-utilities] CLI support for port auto negotiation (sonic-net#1568)
#### 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
1 parent a71ff02 commit 8c2980a

14 files changed

+735
-9
lines changed

config/main.py

+120
Original file line numberDiff line numberDiff line change
@@ -3014,6 +3014,126 @@ def speed(ctx, interface_name, interface_speed, verbose):
30143014
command += " -vv"
30153015
clicommon.run_command(command, display_cmd=verbose)
30163016

3017+
#
3018+
# 'autoneg' subcommand
3019+
#
3020+
3021+
@interface.command()
3022+
@click.pass_context
3023+
@click.argument('interface_name', metavar='<interface_name>', required=True)
3024+
@click.argument('mode', metavar='<mode>', required=True, type=click.Choice(["enabled", "disabled"]))
3025+
@click.option('-v', '--verbose', is_flag=True, help="Enable verbose output")
3026+
def autoneg(ctx, interface_name, mode, verbose):
3027+
"""Set interface auto negotiation mode"""
3028+
# Get the config_db connector
3029+
config_db = ctx.obj['config_db']
3030+
3031+
if clicommon.get_interface_naming_mode() == "alias":
3032+
interface_name = interface_alias_to_name(config_db, interface_name)
3033+
if interface_name is None:
3034+
ctx.fail("'interface_name' is None!")
3035+
3036+
log.log_info("'interface autoneg {} {}' executing...".format(interface_name, mode))
3037+
3038+
if ctx.obj['namespace'] is DEFAULT_NAMESPACE:
3039+
command = "portconfig -p {} -an {}".format(interface_name, mode)
3040+
else:
3041+
command = "portconfig -p {} -an {} -n {}".format(interface_name, mode, ctx.obj['namespace'])
3042+
3043+
if verbose:
3044+
command += " -vv"
3045+
clicommon.run_command(command, display_cmd=verbose)
3046+
3047+
#
3048+
# 'adv-speeds' subcommand
3049+
#
3050+
3051+
@interface.command()
3052+
@click.pass_context
3053+
@click.argument('interface_name', metavar='<interface_name>', required=True)
3054+
@click.argument('speed_list', metavar='<speed_list>', required=True)
3055+
@click.option('-v', '--verbose', is_flag=True, help="Enable verbose output")
3056+
def advertised_speeds(ctx, interface_name, speed_list, verbose):
3057+
"""Set interface advertised speeds"""
3058+
# Get the config_db connector
3059+
config_db = ctx.obj['config_db']
3060+
3061+
if clicommon.get_interface_naming_mode() == "alias":
3062+
interface_name = interface_alias_to_name(config_db, interface_name)
3063+
if interface_name is None:
3064+
ctx.fail("'interface_name' is None!")
3065+
3066+
log.log_info("'interface advertised_speeds {} {}' executing...".format(interface_name, speed_list))
3067+
3068+
if ctx.obj['namespace'] is DEFAULT_NAMESPACE:
3069+
command = "portconfig -p {} -S {}".format(interface_name, speed_list)
3070+
else:
3071+
command = "portconfig -p {} -S {} -n {}".format(interface_name, speed_list, ctx.obj['namespace'])
3072+
3073+
if verbose:
3074+
command += " -vv"
3075+
clicommon.run_command(command, display_cmd=verbose)
3076+
3077+
#
3078+
# 'interface-type' subcommand
3079+
#
3080+
3081+
@interface.command(name='type')
3082+
@click.pass_context
3083+
@click.argument('interface_name', metavar='<interface_name>', required=True)
3084+
@click.argument('interface_type_value', metavar='<interface_type_value>', required=True)
3085+
@click.option('-v', '--verbose', is_flag=True, help="Enable verbose output")
3086+
def interface_type(ctx, interface_name, interface_type_value, verbose):
3087+
"""Set interface type"""
3088+
# Get the config_db connector
3089+
config_db = ctx.obj['config_db']
3090+
3091+
if clicommon.get_interface_naming_mode() == "alias":
3092+
interface_name = interface_alias_to_name(config_db, interface_name)
3093+
if interface_name is None:
3094+
ctx.fail("'interface_name' is None!")
3095+
3096+
log.log_info("'interface interface_type {} {}' executing...".format(interface_name, interface_type_value))
3097+
3098+
if ctx.obj['namespace'] is DEFAULT_NAMESPACE:
3099+
command = "portconfig -p {} -t {}".format(interface_name, interface_type_value)
3100+
else:
3101+
command = "portconfig -p {} -t {} -n {}".format(interface_name, interface_type_value, ctx.obj['namespace'])
3102+
3103+
if verbose:
3104+
command += " -vv"
3105+
clicommon.run_command(command, display_cmd=verbose)
3106+
3107+
#
3108+
# 'advertised-interface-types' subcommand
3109+
#
3110+
3111+
@interface.command()
3112+
@click.pass_context
3113+
@click.argument('interface_name', metavar='<interface_name>', required=True)
3114+
@click.argument('interface_type_list', metavar='<interface_type_list>', required=True)
3115+
@click.option('-v', '--verbose', is_flag=True, help="Enable verbose output")
3116+
def advertised_types(ctx, interface_name, interface_type_list, verbose):
3117+
"""Set interface advertised types"""
3118+
# Get the config_db connector
3119+
config_db = ctx.obj['config_db']
3120+
3121+
if clicommon.get_interface_naming_mode() == "alias":
3122+
interface_name = interface_alias_to_name(config_db, interface_name)
3123+
if interface_name is None:
3124+
ctx.fail("'interface_name' is None!")
3125+
3126+
log.log_info("'interface advertised_interface_types {} {}' executing...".format(interface_name, interface_type_list))
3127+
3128+
if ctx.obj['namespace'] is DEFAULT_NAMESPACE:
3129+
command = "portconfig -p {} -T {}".format(interface_name, interface_type_list)
3130+
else:
3131+
command = "portconfig -p {} -T {} -n {}".format(interface_name, interface_type_list, ctx.obj['namespace'])
3132+
3133+
if verbose:
3134+
command += " -vv"
3135+
clicommon.run_command(command, display_cmd=verbose)
3136+
30173137
#
30183138
# 'breakout' subcommand
30193139
#

doc/Command-Reference.md

+127
Original file line numberDiff line numberDiff line change
@@ -3064,6 +3064,7 @@ Subsequent pages explain each of these commands in detail.
30643064
-?, -h, --help Show this message and exit.
30653065

30663066
Commands:
3067+
autoneg Show interface autoneg information
30673068
breakout Show Breakout Mode information by interfaces
30683069
counters Show interface counters
30693070
description Show interface status, protocol and...
@@ -3074,6 +3075,30 @@ Subsequent pages explain each of these commands in detail.
30743075
transceiver Show SFP Transceiver information
30753076
```
30763077
3078+
**show interfaces autoneg**
3079+
3080+
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.
3081+
3082+
- Usage:
3083+
```
3084+
show interfaces autoneg status
3085+
show interfaces autoneg status <interface_name>
3086+
```
3087+
3088+
- Example:
3089+
```
3090+
admin@sonic:~$ show interfaces autoneg status
3091+
Interface Auto-Neg Mode Speed Adv Speeds Type Adv Types Oper Admin
3092+
----------- --------------- ------- ------------ ------ ----------- ------ -------
3093+
Ethernet0 enabled 25G 10G,25G CR CR,CR4 up up
3094+
Ethernet4 disabled 100G all CR4 all up up
3095+
3096+
admin@sonic:~$ show interfaces autoneg status Ethernet8
3097+
Interface Auto-Neg Mode Speed Adv Speeds Type Adv Types Oper Admin
3098+
----------- --------------- ------- ------------ ------ ----------- ------ -------
3099+
Ethernet8 disabled 100G N/A CR4 N/A up up
3100+
```
3101+
30773102
**show interfaces breakout**
30783103
30793104
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.
@@ -3380,6 +3405,10 @@ This sub-section explains the following list of configuration on the interfaces.
33803405
4) speed - to set the interface speed
33813406
5) startup - to bring up the administratively shutdown interface
33823407
6) breakout - to set interface breakout mode
3408+
7) autoneg - to set interface auto negotiation mode
3409+
8) advertised-speeds - to set interface advertised speeds
3410+
9) advertised-types - to set interface advertised types
3411+
10) type - to set interface type
33833412
33843413
From 201904 release onwards, the “config interface” command syntax is changed and the format is as follows:
33853414
@@ -3714,6 +3743,104 @@ kindly use, double tab i.e. <tab><tab> to see the available breakout option cust
37143743
37153744
Go Back To [Beginning of the document](#) or [Beginning of this section](#interfaces)
37163745
3746+
**config interface autoneg <interface_name> (Versions >= 202106)**
3747+
3748+
This command is used to set port auto negotiation mode.
3749+
3750+
- Usage:
3751+
```
3752+
sudo config interface autoneg --help
3753+
Usage: config interface autoneg [OPTIONS] <interface_name> <mode>
3754+
3755+
Set interface auto negotiation mode
3756+
3757+
Options:
3758+
-v, --verbose Enable verbose output
3759+
-h, -?, --help Show this message and exit.
3760+
```
3761+
3762+
- Example:
3763+
```
3764+
admin@sonic:~$ sudo config interface autoneg Ethernet0 enabled
3765+
3766+
admin@sonic:~$ sudo config interface autoneg Ethernet0 disabled
3767+
```
3768+
3769+
Go Back To [Beginning of the document](#) or [Beginning of this section](#interfaces)
3770+
3771+
**config interface advertised-speeds <interface_name> (Versions >= 202106)**
3772+
3773+
This command is used to set port advertised speed.
3774+
3775+
- Usage:
3776+
```
3777+
sudo config interface advertised-speeds --help
3778+
Usage: config interface advertised-speeds [OPTIONS] <interface_name> <speed_list>
3779+
3780+
Set interface advertised speeds
3781+
3782+
Options:
3783+
-v, --verbose Enable verbose output
3784+
-h, -?, --help Show this message and exit.
3785+
```
3786+
3787+
- Example:
3788+
```
3789+
admin@sonic:~$ sudo config interface advertised-speeds Ethernet0 all
3790+
3791+
admin@sonic:~$ sudo config interface advertised-speeds Ethernet0 50000,100000
3792+
```
3793+
3794+
Go Back To [Beginning of the document](#) or [Beginning of this section](#interfaces)
3795+
3796+
**config interface advertised-types <interface_name> (Versions >= 202106)**
3797+
3798+
This command is used to set port advertised interface types.
3799+
3800+
- Usage:
3801+
```
3802+
sudo config interface advertised-types --help
3803+
Usage: config interface advertised-types [OPTIONS] <interface_name> <interface_type_list>
3804+
3805+
Set interface advertised types
3806+
3807+
Options:
3808+
-v, --verbose Enable verbose output
3809+
-h, -?, --help Show this message and exit.
3810+
```
3811+
3812+
- Example:
3813+
```
3814+
admin@sonic:~$ sudo config interface advertised-types Ethernet0 all
3815+
3816+
admin@sonic:~$ sudo config interface advertised-types Ethernet0 CR,CR4
3817+
```
3818+
3819+
Go Back To [Beginning of the document](#) or [Beginning of this section](#interfaces)
3820+
3821+
**config interface type <interface_name> (Versions >= 202106)**
3822+
3823+
This command is used to set port interface type.
3824+
3825+
- Usage:
3826+
```
3827+
sudo config interface type --help
3828+
Usage: config interface type [OPTIONS] <interface_name> <interface_type_value>
3829+
3830+
Set interface type
3831+
3832+
Options:
3833+
-v, --verbose Enable verbose output
3834+
-h, -?, --help Show this message and exit.
3835+
```
3836+
3837+
- Example:
3838+
```
3839+
admin@sonic:~$ sudo config interface type Ethernet0 CR4
3840+
```
3841+
3842+
Go Back To [Beginning of the document](#) or [Beginning of this section](#interfaces)
3843+
37173844
**config interface cable_length (Versions >= 202006)**
37183845
37193846
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".

scripts/db_migrator.py

+21-1
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,18 @@ def prepare_dynamic_buffer_for_warm_reboot(self, buffer_pools=None, buffer_profi
353353

354354
return True
355355

356+
def migrate_config_db_port_table_for_auto_neg(self):
357+
table_name = 'PORT'
358+
port_table = self.configDB.get_table(table_name)
359+
for key, value in port_table.items():
360+
if 'autoneg' in value:
361+
if value['autoneg'] == '1':
362+
self.configDB.set(self.configDB.CONFIG_DB, '{}|{}'.format(table_name, key), 'autoneg', 'on')
363+
if 'speed' in value and 'adv_speeds' not in value:
364+
self.configDB.set(self.configDB.CONFIG_DB, '{}|{}'.format(table_name, key), 'adv_speeds', value['speed'])
365+
elif value['autoneg'] == '0':
366+
self.configDB.set(self.configDB.CONFIG_DB, '{}|{}'.format(table_name, key), 'autoneg', 'off')
367+
356368
def version_unknown(self):
357369
"""
358370
version_unknown tracks all SONiC versions that doesn't have a version
@@ -470,10 +482,18 @@ def version_1_0_5(self):
470482

471483
def version_2_0_0(self):
472484
"""
473-
Current latest version. Nothing to do here.
485+
Version 2_0_0.
474486
"""
475487
log.log_info('Handling version_2_0_0')
488+
self.migrate_config_db_port_table_for_auto_neg()
489+
self.set_version('version_2_0_1')
490+
return 'version_2_0_1'
476491

492+
def version_2_0_1(self):
493+
"""
494+
Current latest version. Nothing to do here.
495+
"""
496+
log.log_info('Handling version_2_0_1')
477497
return None
478498

479499
def get_version(self):

0 commit comments

Comments
 (0)