Skip to content

Commit

Permalink
Merge remote-tracking branch 'public/202305' into 202305
Browse files Browse the repository at this point in the history
  • Loading branch information
gechiang committed Feb 18, 2024
2 parents acc3e5b + 1c5c134 commit d9c7033
Show file tree
Hide file tree
Showing 32 changed files with 1,590,352 additions and 919 deletions.
36 changes: 11 additions & 25 deletions config/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -1679,17 +1679,15 @@ def load_mgmt_config(filename):
clicommon.run_command(command, display_cmd=True, ignore_error=True)
if len(config_data['MGMT_INTERFACE'].keys()) > 0:
filepath = '/var/run/dhclient.eth0.pid'
if not os.path.isfile(filepath):
sys.exit('File {} does not exist'.format(filepath))

out0, rc0 = clicommon.run_command(['cat', filepath], display_cmd=True, return_cmd=True)
if rc0 != 0:
sys.exit('Exit: {}. Command: cat {} failed.'.format(rc0, filepath))

out1, rc1 = clicommon.run_command(['kill', str(out0).strip('\n')], return_cmd=True)
if rc1 != 0:
sys.exit('Exit: {}. Command: kill {} failed.'.format(rc1, out0))
clicommon.run_command(['rm', '-f', filepath], display_cmd=True, return_cmd=True)
if os.path.isfile(filepath):
out0, rc0 = clicommon.run_command(['cat', filepath], display_cmd=True, return_cmd=True)
if rc0 != 0:
sys.exit('Exit: {}. Command: cat {} failed.'.format(rc0, filepath))

out1, rc1 = clicommon.run_command(['kill', str(out0).strip('\n')], display_cmd=True, return_cmd=True)
if rc1 != 0:
sys.exit('Exit: {}. Command: kill {} failed.'.format(rc1, out0))
clicommon.run_command(['rm', '-f', filepath], display_cmd=True, return_cmd=True)
click.echo("Please note loaded setting will be lost after system reboot. To preserve setting, run `config save`.")

@config.command("load_minigraph")
Expand Down Expand Up @@ -1767,7 +1765,7 @@ def load_minigraph(db, no_service_restart, traffic_shift_away, override_config,
cfggen_namespace_option = ['-n', str(namespace)]
clicommon.run_command([db_migrator, '-o', 'set_version'] + cfggen_namespace_option)

# Keep device isolated with TSA
# Keep device isolated with TSA
if traffic_shift_away:
clicommon.run_command(["TSA"], display_cmd=True)
if override_config:
Expand Down Expand Up @@ -2052,21 +2050,9 @@ def synchronous_mode(sync_mode):
config reload -y \n
Option 2. systemctl restart swss""" % sync_mode)

#
# 'suppress-fib-pending' command ('config suppress-fib-pending ...')
#
@config.command('suppress-fib-pending')
@click.argument('state', metavar='<enabled|disabled>', required=True, type=click.Choice(['enabled', 'disabled']))
@clicommon.pass_db
def suppress_pending_fib(db, state):
''' Enable or disable pending FIB suppression. Once enabled, BGP will not advertise routes that are not yet installed in the hardware '''

config_db = db.cfgdb
config_db.mod_entry('DEVICE_METADATA' , 'localhost', {"suppress-fib-pending" : state})

#
# 'yang_config_validation' command ('config yang_config_validation ...')
#
#
@config.command('yang_config_validation')
@click.argument('yang_config_validation', metavar='<enable|disable>', required=True)
def yang_config_validation(yang_config_validation):
Expand Down
83 changes: 83 additions & 0 deletions config/syslog.py
Original file line number Diff line number Diff line change
Expand Up @@ -471,3 +471,86 @@ def rate_limit_container(db, service_name, interval, burst):
feature_data = db.cfgdb.get_table(syslog_common.FEATURE_TABLE)
syslog_common.service_validator(feature_data, service_name)
syslog_common.save_rate_limit_to_db(db, service_name, interval, burst, log)


@syslog.group(
name="rate-limit-feature",
cls=clicommon.AliasedGroup
)
def rate_limit_feature():
""" Configure syslog rate limit feature """
pass


@rate_limit_feature.command("enable")
@clicommon.pass_db
def enable_rate_limit_feature(db):
""" Enable syslog rate limit feature """
feature_data = db.cfgdb.get_table(syslog_common.FEATURE_TABLE)
for feature_name in feature_data.keys():
click.echo(f'Enabling syslog rate limit feature for {feature_name}')
output, _ = clicommon.run_command(['docker', 'ps', '-q', '-f', 'status=running', '-f', f'name={feature_name}'], return_cmd=True)
if not output:
click.echo(f'{feature_name} is not running, ignoring...')
continue

output, _ = clicommon.run_command(['docker', 'exec', '-i', feature_name, 'supervisorctl', 'status', 'containercfgd'],
ignore_error=True, return_cmd=True)
if 'no such process' not in output:
click.echo(f'Syslog rate limit feature is already enabled in {feature_name}, ignoring...')
continue

commands = [
['docker', 'cp', '/usr/share/sonic/templates/containercfgd.conf', f'{feature_name}:/etc/supervisor/conf.d/'],
['docker', 'exec', '-i', feature_name, 'supervisorctl', 'reread'],
['docker', 'exec', '-i', feature_name, 'supervisorctl', 'update'],
['docker', 'exec', '-i', feature_name, 'supervisorctl', 'start', 'containercfgd']
]

failed = False
for command in commands:
output, ret = clicommon.run_command(command, return_cmd=True)
if ret != 0:
failed = True
click.echo(f'Enable syslog rate limit feature for {feature_name} failed - {output}')
break

if not failed:
click.echo(f'Enabled syslog rate limit feature for {feature_name}')


@rate_limit_feature.command("disable")
@clicommon.pass_db
def disable_rate_limit_feature(db):
""" Disable syslog rate limit feature """
feature_data = db.cfgdb.get_table(syslog_common.FEATURE_TABLE)
for feature_name in feature_data.keys():
click.echo(f'Disabling syslog rate limit feature for {feature_name}')
output, _ = clicommon.run_command(['docker', 'ps', '-q', '-f', 'status=running', '-f', f'name={feature_name}'], return_cmd=True)
if not output:
click.echo(f'{feature_name} is not running, ignoring...')
continue

output, _ = clicommon.run_command(['docker', 'exec', '-i', feature_name, 'supervisorctl', 'status', 'containercfgd'],
ignore_error=True, return_cmd=True)
if 'no such process' in output:
click.echo(f'Syslog rate limit feature is already disabled in {feature_name}, ignoring...')
continue

commands = [
['docker', 'exec', '-i', feature_name, 'supervisorctl', 'stop', 'containercfgd'],
['docker', 'exec', '-i', feature_name, 'rm', '-f', '/etc/supervisor/conf.d/containercfgd.conf'],
['docker', 'exec', '-i', feature_name, 'supervisorctl', 'reread'],
['docker', 'exec', '-i', feature_name, 'supervisorctl', 'update']
]
failed = False
for command in commands:
output, ret = clicommon.run_command(command, return_cmd=True)
if ret != 0:
failed = True
click.echo(f'Disable syslog rate limit feature for {feature_name} failed - {output}')
break

if not failed:
click.echo(f'Disabled syslog rate limit feature for {feature_name}')

65 changes: 27 additions & 38 deletions doc/Command-Reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -2434,26 +2434,6 @@ This command displays the routing policy that takes precedence over the other ro
Exit routemap
```
**show suppress-fib-pending**
This command is used to show the status of suppress pending FIB feature.
When enabled, BGP will not advertise routes which aren't yet offloaded.
- Usage:
```
show suppress-fib-pending
```
- Examples:
```
admin@sonic:~$ show suppress-fib-pending
Enabled
```
```
admin@sonic:~$ show suppress-fib-pending
Disabled
```
Go Back To [Beginning of the document](#) or [Beginning of this section](#bgp)
### BGP config commands
Expand Down Expand Up @@ -2546,24 +2526,6 @@ This command is used to remove particular IPv4 or IPv6 BGP neighbor configuratio
admin@sonic:~$ sudo config bgp remove neighbor SONIC02SPINE
```
**config suppress-fib-pending**
This command is used to enable or disable announcements of routes not yet installed in the HW.
Once enabled, BGP will not advertise routes which aren't yet offloaded.
- Usage:
```
config suppress-fib-pending <enabled|disabled>
```
- Examples:
```
admin@sonic:~$ sudo config suppress-fib-pending enabled
```
```
admin@sonic:~$ sudo config suppress-fib-pending disabled
```
Go Back To [Beginning of the document](#) or [Beginning of this section](#bgp)
## Console
Expand Down Expand Up @@ -9893,6 +9855,33 @@ This command is used to configure syslog rate limit for containers.
admin@sonic:~$ sudo config syslog rate-limit-container bgp --interval 300 --burst 20000
```
**config syslog rate-limit-feature enable**
This command is used to enable syslog rate limit feature.
- Usage:
```
config syslog rate-limit-feature enable
```
- Example:
```
admin@sonic:~$ sudo config syslog rate-limit-feature enable
```
**config syslog rate-limit-feature disable**
This command is used to disable syslog rate limit feature.
- Usage:
```
config syslog rate-limit-feature disable
```
- Example:
```
admin@sonic:~$ sudo config syslog rate-limit-feature disable
```
Go Back To [Beginning of the document](#) or [Beginning of this section](#syslog)
Expand Down
77 changes: 75 additions & 2 deletions generic_config_updater/field_operation_validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
import subprocess
from sonic_py_common import device_info
from .gu_common import GenericConfigUpdaterError

from swsscommon import swsscommon
from utilities_common.constants import DEFAULT_SUPPORTED_FECS_LIST

SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__))
GCU_TABLE_MOD_CONF_FILE = f"{SCRIPT_DIR}/gcu_field_operation_validators.conf.json"
Expand Down Expand Up @@ -75,7 +76,7 @@ def rdma_config_update_validator(patch_element):
path = patch_element["path"]
table = jsonpointer.JsonPointer(path).parts[0]

# Helper function to return relevant cleaned paths, consdiers case where the jsonpatch value is a dict
# Helper function to return relevant cleaned paths, considers case where the jsonpatch value is a dict
# For paths like /PFC_WD/Ethernet112/action, remove Ethernet112 from the path so that we can clearly determine the relevant field (i.e. action, not Ethernet112)
def _get_fields_in_patch():
cleaned_fields = []
Expand Down Expand Up @@ -130,3 +131,75 @@ def _get_fields_in_patch():
return False

return True


def read_statedb_entry(table, key, field):
state_db = swsscommon.DBConnector("STATE_DB", 0)
tbl = swsscommon.Table(state_db, table)
return tbl.hget(key, field)[1]


def port_config_update_validator(patch_element):

def _validate_field(field, port, value):
if field == "fec":
supported_fecs_str = read_statedb_entry("PORT_TABLE", port, "supported_fecs")
if supported_fecs_str:
if supported_fecs_str != 'N/A':
supported_fecs_list = [element.strip() for element in supported_fecs_str.split(',')]
else:
supported_fecs_list = []
else:
supported_fecs_list = DEFAULT_SUPPORTED_FECS_LIST
if value.strip() not in supported_fecs_list:
return False
return True
if field == "speed":
supported_speeds_str = read_statedb_entry("PORT_TABLE", port, "supported_speeds") or ''
try:
supported_speeds = [int(s) for s in supported_speeds_str.split(',') if s]
if supported_speeds and int(value) not in supported_speeds:
return False
except ValueError:
return False
return True
return False

def _parse_port_from_path(path):
match = re.search(r"Ethernet\d+", path)
if match:
port = match.group(0)
return port
return None

if patch_element["op"] == "remove":
return True

# for PORT speed and fec configs, need to ensure value is allowed based on StateDB
patch_element_str = json.dumps(patch_element)
path = patch_element["path"]
value = patch_element.get("value")
fields = ['fec', 'speed']
for field in fields:
if field in patch_element_str:
if path.endswith(field):
port = _parse_port_from_path(path)
if not _validate_field(field, port, value):
return False
elif isinstance(value, dict):
if field in value.keys():
port = _parse_port_from_path(path)
value = value[field]
if not _validate_field(field, port, value):
return False
else:
for port_name, port_info in value.items():
if isinstance(port_info, dict):
port = port_name
if field in port_info.keys():
value = port_info[field]
if not _validate_field(field, port, value):
return False
else:
continue
return True
10 changes: 7 additions & 3 deletions generic_config_updater/gcu_field_operation_validators.conf.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@
"helper_data": {
"rdma_config_update_validator": {
"mellanox_asics": {
"spc1": [ "ACS-MSN2700", "ACS-MSN2740", "ACS-MSN2100", "ACS-MSN2410", "ACS-MSN2010", "Mellanox-SN2700", "Mellanox-SN2700-D48C8",
"spc1": [ "ACS-MSN2700", "ACS-MSN2740", "ACS-MSN2100", "ACS-MSN2410", "ACS-MSN2010", "Mellanox-SN2700", "Mellanox-SN2700-C28D8", "Mellanox-SN2700-D40C8S8", "Mellanox-SN2700-D44C10", "Mellanox-SN2700-D48C8",
"ACS-MSN2700-A1", "Mellanox-SN2700-A1", "Mellanox-SN2700-A1-C28D8", "Mellanox-SN2700-A1-D40C8S8", "Mellanox-SN2700-A1-D44C10", "Mellanox-SN2700-A1-D48C8" ],
"spc2": [ "ACS-MSN3800", "Mellanox-SN3800-D112C8" ],
"spc3": [ "ACS-MSN4700", "ACS-MSN4600", "ACS-MSN4600C", "ACS-MSN4410", "Mellanox-SN4600C-D112C8", "Mellanox-SN4600C-C64", "Mellanox-SN4700-O8C48" ],
"spc2": [ "ACS-MSN3800", "Mellanox-SN3800-D112C8", "ACS-MSN3420", "ACS-MSN3700C", "ACS-MSN3700", "Mellanox-SN3800-C64", "Mellanox-SN3800-D100C12S2", "Mellanox-SN3800-D24C52", "Mellanox-SN3800-D28C49S1", "Mellanox-SN3800-D28C50" ],
"spc3": [ "ACS-MSN4700", "ACS-MSN4600", "ACS-MSN4600C", "ACS-MSN4410", "Mellanox-SN4600C-D112C8", "Mellanox-SN4600C-C64", "Mellanox-SN4700-O8C48", "Mellanox-SN4600C-D100C12S2", "Mellanox-SN4600C-D48C40",
"Mellanox-SN4700-A96C8V8", "Mellanox-SN4700-C128", "Mellanox-SN4700-O28", "Mellanox-SN4700-O8V48", "Mellanox-SN4700-V48C32"],
"spc4": [ "ACS-SN5600"]
},
"broadcom_asics": {
Expand Down Expand Up @@ -152,6 +153,9 @@
}
}
}
},
"PORT": {
"field_operation_validators": [ "generic_config_updater.field_operation_validators.port_config_update_validator" ]
}
}
}
Loading

0 comments on commit d9c7033

Please sign in to comment.