Skip to content

Commit 9e0295f

Browse files
authored
Merge branch 'master' into master-fabric-monitor-feature-toggle-command
2 parents cac9fef + 359e692 commit 9e0295f

File tree

123 files changed

+1597604
-2286
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

123 files changed

+1597604
-2286
lines changed

acl_loader/main.py

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,31 @@ def read_tables_info(self):
173173
Read ACL_TABLE table from configuration database
174174
:return:
175175
"""
176-
self.tables_db_info = self.configdb.get_table(self.ACL_TABLE)
176+
# get the acl table info from host config_db
177+
host_acl_table = self.configdb.get_table(self.ACL_TABLE)
178+
# For multi asic get only the control plane acls from the host config_db
179+
if self.per_npu_configdb:
180+
for table, entry in host_acl_table.items():
181+
if entry.get('type', None) != self.ACL_TABLE_TYPE_CTRLPLANE:
182+
continue
183+
184+
self.tables_db_info[table] = entry
185+
else:
186+
self.tables_db_info.update(host_acl_table)
187+
188+
# for DATAACL, EVERFLOW acls.
189+
# update the ports from all the namespaces
190+
if self.per_npu_configdb:
191+
for ns, config_db in self.per_npu_configdb.items():
192+
acl_table = config_db.get_table(self.ACL_TABLE)
193+
for table, entry in acl_table.items():
194+
if entry.get('type', None) == self.ACL_TABLE_TYPE_CTRLPLANE:
195+
continue
196+
if table not in self.tables_db_info:
197+
self.tables_db_info[table] = entry
198+
else:
199+
self.tables_db_info[table]['ports'] += entry.get(
200+
'ports', [])
177201

178202
def get_tables_db_info(self):
179203
return self.tables_db_info
@@ -574,6 +598,14 @@ def convert_icmp(self, table_name, rule_idx, rule):
574598
is_rule_v6 = True
575599
except Exception as e:
576600
pass
601+
else:
602+
# get the IP version type using IP_PROTOCOL.
603+
try:
604+
ip_protocol = rule.ip.config.protocol
605+
if ip_protocol == "IP_ICMPV6" or int(ip_protocol) == self.ip_protocol_map["IP_ICMPV6"]:
606+
is_rule_v6 = True
607+
except Exception as e:
608+
pass
577609

578610
type_key = "ICMPV6_TYPE" if is_rule_v6 else "ICMP_TYPE"
579611
code_key = "ICMPV6_CODE" if is_rule_v6 else "ICMP_CODE"

azure-pipelines.yml

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,13 @@ resources:
1313
name: sonic-net/sonic-swss
1414
endpoint: sonic-net
1515

16+
variables:
17+
- name: BUILD_BRANCH
18+
${{ if eq(variables['Build.Reason'], 'PullRequest') }}:
19+
value: $(System.PullRequest.TargetBranch)
20+
${{ else }}:
21+
value: $(Build.SourceBranchName)
22+
1623
stages:
1724
- stage: Build
1825

@@ -26,7 +33,7 @@ stages:
2633
vmImage: ubuntu-20.04
2734

2835
container:
29-
image: sonicdev-microsoft.azurecr.io:443/sonic-slave-bullseye:latest
36+
image: sonicdev-microsoft.azurecr.io:443/sonic-slave-bullseye:$(BUILD_BRANCH)
3037

3138
steps:
3239
- script: |
@@ -52,12 +59,11 @@ stages:
5259

5360
- script: |
5461
set -xe
55-
sudo apt-get -y purge libhiredis-dev libnl-3-dev libnl-route-3-dev || true
62+
sudo apt-get -y purge libnl-3-dev libnl-route-3-dev || true
5663
sudo dpkg -i libnl-3-200_*.deb
5764
sudo dpkg -i libnl-genl-3-200_*.deb
5865
sudo dpkg -i libnl-route-3-200_*.deb
5966
sudo dpkg -i libnl-nf-3-200_*.deb
60-
sudo dpkg -i libhiredis0.14_*.deb
6167
sudo dpkg -i libyang_1.0.73_amd64.deb
6268
sudo dpkg -i libyang-cpp_1.0.73_amd64.deb
6369
sudo dpkg -i python3-yang_1.0.73_amd64.deb

clear/main.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,18 @@ def queuecounters():
184184
command = ["queuestat", "-c", "--voq"]
185185
run_command(command)
186186

187+
@cli.command()
188+
def fabriccountersqueue():
189+
"""Clear fabric queue counters"""
190+
command = ["fabricstat", "-C", "-q"]
191+
run_command(command)
192+
193+
@cli.command()
194+
def fabriccountersport():
195+
"""Clear fabric port counters"""
196+
command = ["fabricstat", "-C"]
197+
run_command(command)
198+
187199
@cli.command()
188200
def pfccounters():
189201
"""Clear pfc counters"""

config/main.py

Lines changed: 134 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import time
1515
import itertools
1616
import copy
17+
import tempfile
1718

1819
from jsonpatch import JsonPatchConflict
1920
from jsonpointer import JsonPointerException
@@ -33,7 +34,7 @@
3334
from utilities_common.intf_filter import parse_interface_in_filter
3435
from utilities_common import bgp_util
3536
import utilities_common.cli as clicommon
36-
from utilities_common.helper import get_port_pbh_binding, get_port_acl_binding
37+
from utilities_common.helper import get_port_pbh_binding, get_port_acl_binding, update_config
3738
from utilities_common.general import load_db_config, load_module_from_source
3839
from .validated_config_db_connector import ValidatedConfigDBConnector
3940
import utilities_common.multi_asic as multi_asic_util
@@ -142,6 +143,14 @@ def read_json_file(fileName):
142143
raise Exception(str(e))
143144
return result
144145

146+
# write given JSON file
147+
def write_json_file(json_input, fileName):
148+
try:
149+
with open(fileName, 'w') as f:
150+
json.dump(json_input, f, indent=4)
151+
except Exception as e:
152+
raise Exception(str(e))
153+
145154
def _get_breakout_options(ctx, args, incomplete):
146155
""" Provides dynamic mode option as per user argument i.e. interface name """
147156
all_mode_options = []
@@ -1525,6 +1534,12 @@ def reload(db, filename, yes, load_sysinfo, no_service_restart, force, file_form
15251534
# Get the file from user input, else take the default file /etc/sonic/config_db{NS_id}.json
15261535
if cfg_files:
15271536
file = cfg_files[inst+1]
1537+
# Save to tmpfile in case of stdin input which can only be read once
1538+
if file == "/dev/stdin":
1539+
file_input = read_json_file(file)
1540+
(_, tmpfname) = tempfile.mkstemp(dir="/tmp", suffix="_configReloadStdin")
1541+
write_json_file(file_input, tmpfname)
1542+
file = tmpfname
15281543
else:
15291544
if file_format == 'config_db':
15301545
if namespace is None:
@@ -1540,6 +1555,19 @@ def reload(db, filename, yes, load_sysinfo, no_service_restart, force, file_form
15401555
click.echo("The config file {} doesn't exist".format(file))
15411556
continue
15421557

1558+
if file_format == 'config_db':
1559+
file_input = read_json_file(file)
1560+
1561+
platform = file_input.get("DEVICE_METADATA", {}).\
1562+
get("localhost", {}).get("platform")
1563+
mac = file_input.get("DEVICE_METADATA", {}).\
1564+
get("localhost", {}).get("mac")
1565+
1566+
if not platform or not mac:
1567+
log.log_warning("Input file does't have platform or mac. platform: {}, mac: {}"
1568+
.format(None if platform is None else platform, None if mac is None else mac))
1569+
load_sysinfo = True
1570+
15431571
if load_sysinfo:
15441572
try:
15451573
command = [SONIC_CFGGEN_PATH, "-j", file, '-v', "DEVICE_METADATA.localhost.hwsku"]
@@ -1598,6 +1626,13 @@ def reload(db, filename, yes, load_sysinfo, no_service_restart, force, file_form
15981626
clicommon.run_command(command, display_cmd=True)
15991627
client.set(config_db.INIT_INDICATOR, 1)
16001628

1629+
if os.path.exists(file) and file.endswith("_configReloadStdin"):
1630+
# Remove tmpfile
1631+
try:
1632+
os.remove(file)
1633+
except OSError as e:
1634+
click.echo("An error occurred while removing the temporary file: {}".format(str(e)), err=True)
1635+
16011636
# Migrate DB contents to latest version
16021637
db_migrator='/usr/local/bin/db_migrator.py'
16031638
if os.path.isfile(db_migrator) and os.access(db_migrator, os.X_OK):
@@ -1907,14 +1942,15 @@ def override_config_table(db, input_config_db, dry_run):
19071942
if ns in config_input.keys():
19081943
ns_config_input = config_input[ns]
19091944
else:
1910-
click.secho("Wrong config format! {} not found in asic config! cannot override.. abort".format(ns))
1911-
sys.exit(1)
1945+
click.echo("Override config not present for {}".format(ns))
1946+
continue
19121947
if not ns_config_input:
19131948
# if ns_config_input is not defined, define it
19141949
# it could be single-asic dut, or config_input is empty
19151950
ns_config_input = config_input
19161951
# Generate sysinfo if missing in ns_config_input
19171952
generate_sysinfo(current_config, ns_config_input, ns)
1953+
# Use deepcopy by default to avoid modifying input config
19181954
updated_config = update_config(current_config, ns_config_input)
19191955

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

19521988

1953-
def update_config(current_config, config_input):
1954-
updated_config = copy.deepcopy(current_config)
1955-
# Override current config with golden config
1956-
for table in config_input:
1957-
updated_config[table] = config_input[table]
1958-
return updated_config
1959-
1960-
19611989
def override_config_db(config_db, config_input):
19621990
# Deserialized golden config to DB recognized format
19631991
sonic_cfggen.FormatConverter.to_deserialized(config_input)
@@ -2909,7 +2937,12 @@ def _qos_update_ports(ctx, ports, dry_run, json_data):
29092937
click.secho("QoS definition template not found at {}".format(qos_template_file), fg="yellow")
29102938
ctx.abort()
29112939

2912-
# Remove multi indexed entries first
2940+
# Remove entries first
2941+
for table_name in tables_single_index:
2942+
for port in portset_to_handle:
2943+
if config_db.get_entry(table_name, port):
2944+
config_db.set_entry(table_name, port, None)
2945+
29132946
for table_name in tables_multi_index:
29142947
entries = config_db.get_keys(table_name)
29152948
for key in entries:
@@ -5960,6 +5993,22 @@ def ecn(profile, rmax, rmin, ymax, ymin, gmax, gmin, rdrop, ydrop, gdrop, verbos
59605993
clicommon.run_command(command, display_cmd=verbose)
59615994

59625995

5996+
#
5997+
# 'mmu' command ('config mmu...')
5998+
#
5999+
@config.command()
6000+
@click.option('-p', metavar='<profile_name>', type=str, required=True, help="Profile name")
6001+
@click.option('-a', metavar='<alpha>', type=click.IntRange(-8,8), help="Set alpha for profile type dynamic")
6002+
@click.option('-s', metavar='<staticth>', type=int, help="Set staticth for profile type static")
6003+
def mmu(p, a, s):
6004+
"""mmuconfig configuration tasks"""
6005+
log.log_info("'mmuconfig -p {}' executing...".format(p))
6006+
command = ['mmuconfig', '-p', str(p)]
6007+
if a is not None: command += ['-a', str(a)]
6008+
if s is not None: command += ['-s', str(s)]
6009+
clicommon.run_command(command)
6010+
6011+
59636012
#
59646013
# 'pfc' group ('config interface pfc ...')
59656014
#
@@ -6525,7 +6574,9 @@ def add_ntp_server(ctx, ntp_ip_address):
65256574
return
65266575
else:
65276576
try:
6528-
db.set_entry('NTP_SERVER', ntp_ip_address, {'NULL': 'NULL'})
6577+
db.set_entry('NTP_SERVER', ntp_ip_address,
6578+
{'resolve_as': ntp_ip_address,
6579+
'association_type': 'server'})
65296580
except ValueError as e:
65306581
ctx.fail("Invalid ConfigDB. Error: {}".format(e))
65316582
click.echo("NTP server {} added to configuration".format(ntp_ip_address))
@@ -6646,6 +6697,41 @@ def polling_int(ctx, interval):
66466697
except ValueError as e:
66476698
ctx.fail("Invalid ConfigDB. Error: {}".format(e))
66486699

6700+
def is_port_egress_sflow_supported():
6701+
state_db = SonicV2Connector(use_unix_socket_path=True)
6702+
state_db.connect(state_db.STATE_DB, False)
6703+
entry_name="SWITCH_CAPABILITY|switch"
6704+
supported = state_db.get(state_db.STATE_DB, entry_name,"PORT_EGRESS_SAMPLE_CAPABLE")
6705+
return supported
6706+
6707+
#
6708+
# 'sflow' command ('config sflow sample-direction ...')
6709+
#
6710+
@sflow.command('sample-direction')
6711+
@click.argument('direction', metavar='<sample_direction>', required=True, type=str)
6712+
@click.pass_context
6713+
def global_sample_direction(ctx, direction):
6714+
"""Set sampling direction """
6715+
if ADHOC_VALIDATION:
6716+
if direction:
6717+
if direction not in ['rx', 'tx', 'both']:
6718+
ctx.fail("Error: Direction {} is invalid".format(direction))
6719+
6720+
if ((direction == 'tx' or direction == 'both') and (is_port_egress_sflow_supported() == 'false')):
6721+
ctx.fail("Sample direction {} is not supported on this platform".format(direction))
6722+
6723+
config_db = ValidatedConfigDBConnector(ctx.obj['db'])
6724+
sflow_tbl = config_db.get_table('SFLOW')
6725+
6726+
if not sflow_tbl:
6727+
sflow_tbl = {'global': {'admin_state': 'down'}}
6728+
6729+
sflow_tbl['global']['sample_direction'] = direction
6730+
try:
6731+
config_db.mod_entry('SFLOW', 'global', sflow_tbl['global'])
6732+
except ValueError as e:
6733+
ctx.fail("Invalid ConfigDB. Error: {}".format(e))
6734+
66496735
def is_valid_sample_rate(rate):
66506736
return rate.isdigit() and int(rate) in range(256, 8388608 + 1)
66516737

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

6844+
#
6845+
# 'sflow' command ('config sflow interface sample-direction ...')
6846+
#
6847+
@interface.command('sample-direction')
6848+
@click.argument('ifname', metavar='<interface_name>', required=True, type=str)
6849+
@click.argument('direction', metavar='<sample_direction>', required=True, type=str)
6850+
@click.pass_context
6851+
def interface_sample_direction(ctx, ifname, direction):
6852+
config_db = ValidatedConfigDBConnector(ctx.obj['db'])
6853+
if ADHOC_VALIDATION:
6854+
if not interface_name_is_valid(config_db, ifname) and ifname != 'all':
6855+
click.echo('Invalid interface name')
6856+
return
6857+
if direction:
6858+
if direction not in ['rx', 'tx', 'both']:
6859+
ctx.fail("Error: Direction {} is invalid".format(direction))
6860+
6861+
if (direction == 'tx' or direction == 'both') and (is_port_egress_sflow_supported() == 'false'):
6862+
ctx.fail("Sample direction {} is not supported on this platform".format(direction))
6863+
6864+
sess_dict = config_db.get_table('SFLOW_SESSION')
6865+
6866+
if sess_dict and ifname in sess_dict.keys():
6867+
sess_dict[ifname]['sample_direction'] = direction
6868+
try:
6869+
config_db.mod_entry('SFLOW_SESSION', ifname, sess_dict[ifname])
6870+
except ValueError as e:
6871+
ctx.fail("Invalid ConfigDB. Error: {}".format(e))
6872+
else:
6873+
try:
6874+
config_db.mod_entry('SFLOW_SESSION', ifname, {'sample_direction': direction})
6875+
except ValueError as e:
6876+
ctx.fail("Invalid ConfigDB. Error: {}".format(e))
6877+
67586878

67596879
#
67606880
# 'sflow collector' group
@@ -7203,7 +7323,7 @@ def clock():
72037323

72047324

72057325
def get_tzs(ctx, args, incomplete):
7206-
ret = clicommon.run_command('timedatectl list-timezones',
7326+
ret = clicommon.run_command(['timedatectl', 'list-timezones'],
72077327
display_cmd=False, ignore_error=False,
72087328
return_cmd=True)
72097329
if len(ret) == 0:

0 commit comments

Comments
 (0)