Skip to content

Commit

Permalink
Merge branch 'master' into master-fabric-monitor-feature-toggle-command
Browse files Browse the repository at this point in the history
  • Loading branch information
jfeng-arista committed Jan 11, 2024
2 parents cac9fef + 359e692 commit 9e0295f
Show file tree
Hide file tree
Showing 123 changed files with 1,597,604 additions and 2,286 deletions.
34 changes: 33 additions & 1 deletion acl_loader/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,31 @@ def read_tables_info(self):
Read ACL_TABLE table from configuration database
:return:
"""
self.tables_db_info = self.configdb.get_table(self.ACL_TABLE)
# get the acl table info from host config_db
host_acl_table = self.configdb.get_table(self.ACL_TABLE)
# For multi asic get only the control plane acls from the host config_db
if self.per_npu_configdb:
for table, entry in host_acl_table.items():
if entry.get('type', None) != self.ACL_TABLE_TYPE_CTRLPLANE:
continue

self.tables_db_info[table] = entry
else:
self.tables_db_info.update(host_acl_table)

# for DATAACL, EVERFLOW acls.
# update the ports from all the namespaces
if self.per_npu_configdb:
for ns, config_db in self.per_npu_configdb.items():
acl_table = config_db.get_table(self.ACL_TABLE)
for table, entry in acl_table.items():
if entry.get('type', None) == self.ACL_TABLE_TYPE_CTRLPLANE:
continue
if table not in self.tables_db_info:
self.tables_db_info[table] = entry
else:
self.tables_db_info[table]['ports'] += entry.get(
'ports', [])

def get_tables_db_info(self):
return self.tables_db_info
Expand Down Expand Up @@ -574,6 +598,14 @@ def convert_icmp(self, table_name, rule_idx, rule):
is_rule_v6 = True
except Exception as e:
pass
else:
# get the IP version type using IP_PROTOCOL.
try:
ip_protocol = rule.ip.config.protocol
if ip_protocol == "IP_ICMPV6" or int(ip_protocol) == self.ip_protocol_map["IP_ICMPV6"]:
is_rule_v6 = True
except Exception as e:
pass

type_key = "ICMPV6_TYPE" if is_rule_v6 else "ICMP_TYPE"
code_key = "ICMPV6_CODE" if is_rule_v6 else "ICMP_CODE"
Expand Down
12 changes: 9 additions & 3 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@ resources:
name: sonic-net/sonic-swss
endpoint: sonic-net

variables:
- name: BUILD_BRANCH
${{ if eq(variables['Build.Reason'], 'PullRequest') }}:
value: $(System.PullRequest.TargetBranch)
${{ else }}:
value: $(Build.SourceBranchName)

stages:
- stage: Build

Expand All @@ -26,7 +33,7 @@ stages:
vmImage: ubuntu-20.04

container:
image: sonicdev-microsoft.azurecr.io:443/sonic-slave-bullseye:latest
image: sonicdev-microsoft.azurecr.io:443/sonic-slave-bullseye:$(BUILD_BRANCH)

steps:
- script: |
Expand All @@ -52,12 +59,11 @@ stages:

- script: |
set -xe
sudo apt-get -y purge libhiredis-dev libnl-3-dev libnl-route-3-dev || true
sudo apt-get -y purge libnl-3-dev libnl-route-3-dev || true
sudo dpkg -i libnl-3-200_*.deb
sudo dpkg -i libnl-genl-3-200_*.deb
sudo dpkg -i libnl-route-3-200_*.deb
sudo dpkg -i libnl-nf-3-200_*.deb
sudo dpkg -i libhiredis0.14_*.deb
sudo dpkg -i libyang_1.0.73_amd64.deb
sudo dpkg -i libyang-cpp_1.0.73_amd64.deb
sudo dpkg -i python3-yang_1.0.73_amd64.deb
Expand Down
12 changes: 12 additions & 0 deletions clear/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,18 @@ def queuecounters():
command = ["queuestat", "-c", "--voq"]
run_command(command)

@cli.command()
def fabriccountersqueue():
"""Clear fabric queue counters"""
command = ["fabricstat", "-C", "-q"]
run_command(command)

@cli.command()
def fabriccountersport():
"""Clear fabric port counters"""
command = ["fabricstat", "-C"]
run_command(command)

@cli.command()
def pfccounters():
"""Clear pfc counters"""
Expand Down
148 changes: 134 additions & 14 deletions config/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import time
import itertools
import copy
import tempfile

from jsonpatch import JsonPatchConflict
from jsonpointer import JsonPointerException
Expand All @@ -33,7 +34,7 @@
from utilities_common.intf_filter import parse_interface_in_filter
from utilities_common import bgp_util
import utilities_common.cli as clicommon
from utilities_common.helper import get_port_pbh_binding, get_port_acl_binding
from utilities_common.helper import get_port_pbh_binding, get_port_acl_binding, update_config
from utilities_common.general import load_db_config, load_module_from_source
from .validated_config_db_connector import ValidatedConfigDBConnector
import utilities_common.multi_asic as multi_asic_util
Expand Down Expand Up @@ -142,6 +143,14 @@ def read_json_file(fileName):
raise Exception(str(e))
return result

# write given JSON file
def write_json_file(json_input, fileName):
try:
with open(fileName, 'w') as f:
json.dump(json_input, f, indent=4)
except Exception as e:
raise Exception(str(e))

def _get_breakout_options(ctx, args, incomplete):
""" Provides dynamic mode option as per user argument i.e. interface name """
all_mode_options = []
Expand Down Expand Up @@ -1525,6 +1534,12 @@ def reload(db, filename, yes, load_sysinfo, no_service_restart, force, file_form
# Get the file from user input, else take the default file /etc/sonic/config_db{NS_id}.json
if cfg_files:
file = cfg_files[inst+1]
# Save to tmpfile in case of stdin input which can only be read once
if file == "/dev/stdin":
file_input = read_json_file(file)
(_, tmpfname) = tempfile.mkstemp(dir="/tmp", suffix="_configReloadStdin")
write_json_file(file_input, tmpfname)
file = tmpfname
else:
if file_format == 'config_db':
if namespace is None:
Expand All @@ -1540,6 +1555,19 @@ def reload(db, filename, yes, load_sysinfo, no_service_restart, force, file_form
click.echo("The config file {} doesn't exist".format(file))
continue

if file_format == 'config_db':
file_input = read_json_file(file)

platform = file_input.get("DEVICE_METADATA", {}).\
get("localhost", {}).get("platform")
mac = file_input.get("DEVICE_METADATA", {}).\
get("localhost", {}).get("mac")

if not platform or not mac:
log.log_warning("Input file does't have platform or mac. platform: {}, mac: {}"
.format(None if platform is None else platform, None if mac is None else mac))
load_sysinfo = True

if load_sysinfo:
try:
command = [SONIC_CFGGEN_PATH, "-j", file, '-v', "DEVICE_METADATA.localhost.hwsku"]
Expand Down Expand Up @@ -1598,6 +1626,13 @@ def reload(db, filename, yes, load_sysinfo, no_service_restart, force, file_form
clicommon.run_command(command, display_cmd=True)
client.set(config_db.INIT_INDICATOR, 1)

if os.path.exists(file) and file.endswith("_configReloadStdin"):
# Remove tmpfile
try:
os.remove(file)
except OSError as e:
click.echo("An error occurred while removing the temporary file: {}".format(str(e)), err=True)

# Migrate DB contents to latest version
db_migrator='/usr/local/bin/db_migrator.py'
if os.path.isfile(db_migrator) and os.access(db_migrator, os.X_OK):
Expand Down Expand Up @@ -1907,14 +1942,15 @@ def override_config_table(db, input_config_db, dry_run):
if ns in config_input.keys():
ns_config_input = config_input[ns]
else:
click.secho("Wrong config format! {} not found in asic config! cannot override.. abort".format(ns))
sys.exit(1)
click.echo("Override config not present for {}".format(ns))
continue
if not ns_config_input:
# if ns_config_input is not defined, define it
# it could be single-asic dut, or config_input is empty
ns_config_input = config_input
# Generate sysinfo if missing in ns_config_input
generate_sysinfo(current_config, ns_config_input, ns)
# Use deepcopy by default to avoid modifying input config
updated_config = update_config(current_config, ns_config_input)

yang_enabled = device_info.is_yang_config_validation_enabled(config_db)
Expand Down Expand Up @@ -1950,14 +1986,6 @@ def validate_config_by_cm(cm, config_json, jname):
sys.exit(1)


def update_config(current_config, config_input):
updated_config = copy.deepcopy(current_config)
# Override current config with golden config
for table in config_input:
updated_config[table] = config_input[table]
return updated_config


def override_config_db(config_db, config_input):
# Deserialized golden config to DB recognized format
sonic_cfggen.FormatConverter.to_deserialized(config_input)
Expand Down Expand Up @@ -2909,7 +2937,12 @@ def _qos_update_ports(ctx, ports, dry_run, json_data):
click.secho("QoS definition template not found at {}".format(qos_template_file), fg="yellow")
ctx.abort()

# Remove multi indexed entries first
# Remove entries first
for table_name in tables_single_index:
for port in portset_to_handle:
if config_db.get_entry(table_name, port):
config_db.set_entry(table_name, port, None)

for table_name in tables_multi_index:
entries = config_db.get_keys(table_name)
for key in entries:
Expand Down Expand Up @@ -5960,6 +5993,22 @@ def ecn(profile, rmax, rmin, ymax, ymin, gmax, gmin, rdrop, ydrop, gdrop, verbos
clicommon.run_command(command, display_cmd=verbose)


#
# 'mmu' command ('config mmu...')
#
@config.command()
@click.option('-p', metavar='<profile_name>', type=str, required=True, help="Profile name")
@click.option('-a', metavar='<alpha>', type=click.IntRange(-8,8), help="Set alpha for profile type dynamic")
@click.option('-s', metavar='<staticth>', type=int, help="Set staticth for profile type static")
def mmu(p, a, s):
"""mmuconfig configuration tasks"""
log.log_info("'mmuconfig -p {}' executing...".format(p))
command = ['mmuconfig', '-p', str(p)]
if a is not None: command += ['-a', str(a)]
if s is not None: command += ['-s', str(s)]
clicommon.run_command(command)


#
# 'pfc' group ('config interface pfc ...')
#
Expand Down Expand Up @@ -6525,7 +6574,9 @@ def add_ntp_server(ctx, ntp_ip_address):
return
else:
try:
db.set_entry('NTP_SERVER', ntp_ip_address, {'NULL': 'NULL'})
db.set_entry('NTP_SERVER', ntp_ip_address,
{'resolve_as': ntp_ip_address,
'association_type': 'server'})
except ValueError as e:
ctx.fail("Invalid ConfigDB. Error: {}".format(e))
click.echo("NTP server {} added to configuration".format(ntp_ip_address))
Expand Down Expand Up @@ -6646,6 +6697,41 @@ def polling_int(ctx, interval):
except ValueError as e:
ctx.fail("Invalid ConfigDB. Error: {}".format(e))

def is_port_egress_sflow_supported():
state_db = SonicV2Connector(use_unix_socket_path=True)
state_db.connect(state_db.STATE_DB, False)
entry_name="SWITCH_CAPABILITY|switch"
supported = state_db.get(state_db.STATE_DB, entry_name,"PORT_EGRESS_SAMPLE_CAPABLE")
return supported

#
# 'sflow' command ('config sflow sample-direction ...')
#
@sflow.command('sample-direction')
@click.argument('direction', metavar='<sample_direction>', required=True, type=str)
@click.pass_context
def global_sample_direction(ctx, direction):
"""Set sampling direction """
if ADHOC_VALIDATION:
if direction:
if direction not in ['rx', 'tx', 'both']:
ctx.fail("Error: Direction {} is invalid".format(direction))

if ((direction == 'tx' or direction == 'both') and (is_port_egress_sflow_supported() == 'false')):
ctx.fail("Sample direction {} is not supported on this platform".format(direction))

config_db = ValidatedConfigDBConnector(ctx.obj['db'])
sflow_tbl = config_db.get_table('SFLOW')

if not sflow_tbl:
sflow_tbl = {'global': {'admin_state': 'down'}}

sflow_tbl['global']['sample_direction'] = direction
try:
config_db.mod_entry('SFLOW', 'global', sflow_tbl['global'])
except ValueError as e:
ctx.fail("Invalid ConfigDB. Error: {}".format(e))

def is_valid_sample_rate(rate):
return rate.isdigit() and int(rate) in range(256, 8388608 + 1)

Expand Down Expand Up @@ -6755,6 +6841,40 @@ def sample_rate(ctx, ifname, rate):
except ValueError as e:
ctx.fail("Invalid ConfigDB. Error: {}".format(e))

#
# 'sflow' command ('config sflow interface sample-direction ...')
#
@interface.command('sample-direction')
@click.argument('ifname', metavar='<interface_name>', required=True, type=str)
@click.argument('direction', metavar='<sample_direction>', required=True, type=str)
@click.pass_context
def interface_sample_direction(ctx, ifname, direction):
config_db = ValidatedConfigDBConnector(ctx.obj['db'])
if ADHOC_VALIDATION:
if not interface_name_is_valid(config_db, ifname) and ifname != 'all':
click.echo('Invalid interface name')
return
if direction:
if direction not in ['rx', 'tx', 'both']:
ctx.fail("Error: Direction {} is invalid".format(direction))

if (direction == 'tx' or direction == 'both') and (is_port_egress_sflow_supported() == 'false'):
ctx.fail("Sample direction {} is not supported on this platform".format(direction))

sess_dict = config_db.get_table('SFLOW_SESSION')

if sess_dict and ifname in sess_dict.keys():
sess_dict[ifname]['sample_direction'] = direction
try:
config_db.mod_entry('SFLOW_SESSION', ifname, sess_dict[ifname])
except ValueError as e:
ctx.fail("Invalid ConfigDB. Error: {}".format(e))
else:
try:
config_db.mod_entry('SFLOW_SESSION', ifname, {'sample_direction': direction})
except ValueError as e:
ctx.fail("Invalid ConfigDB. Error: {}".format(e))


#
# 'sflow collector' group
Expand Down Expand Up @@ -7203,7 +7323,7 @@ def clock():


def get_tzs(ctx, args, incomplete):
ret = clicommon.run_command('timedatectl list-timezones',
ret = clicommon.run_command(['timedatectl', 'list-timezones'],
display_cmd=False, ignore_error=False,
return_cmd=True)
if len(ret) == 0:
Expand Down

0 comments on commit 9e0295f

Please sign in to comment.