Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/Azure/sonic-utilities int…
Browse files Browse the repository at this point in the history
…o dump_util_copp
  • Loading branch information
vivekrnv committed Jun 23, 2021
2 parents 1208768 + 5708497 commit 66b5873
Show file tree
Hide file tree
Showing 118 changed files with 46,115 additions and 473 deletions.
4 changes: 2 additions & 2 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,10 @@ stages:
set -xe
sudo pip3 install swsssdk-2.0.1-py3-none-any.whl
sudo pip3 install sonic_py_common-1.0-py3-none-any.whl
sudo pip3 install sonic_config_engine-1.0-py3-none-any.whl
sudo pip3 install sonic_platform_common-1.0-py3-none-any.whl
sudo pip3 install sonic_yang_mgmt-1.0-py3-none-any.whl
sudo pip3 install sonic_yang_models-1.0-py3-none-any.whl
sudo pip3 install sonic_config_engine-1.0-py3-none-any.whl
sudo pip3 install sonic_platform_common-1.0-py3-none-any.whl
workingDirectory: $(Pipeline.Workspace)/target/python-wheels/
displayName: 'Install Python dependencies'
Expand Down
118 changes: 112 additions & 6 deletions config/main.py
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@

PORT_MTU = "mtu"
PORT_SPEED = "speed"
PORT_TPID = "tpid"
DEFAULT_TPID = "0x8100"

asic_type = None

Expand Down Expand Up @@ -681,7 +683,6 @@ def _get_sonic_services():

def _reset_failed_services():
for service in _get_sonic_services():
click.echo("Resetting failed status on {}".format(service))
clicommon.run_command("systemctl reset-failed {}".format(service))


Expand All @@ -700,6 +701,32 @@ def _restart_services():
click.echo("Reloading Monit configuration ...")
clicommon.run_command("sudo monit reload")

def _get_delay_timers():
out = clicommon.run_command("systemctl list-dependencies sonic-delayed.target --plain |sed '1d'", return_cmd=True)
return [timer.strip() for timer in out.splitlines()]

def _delay_timers_elapsed():
for timer in _get_delay_timers():
out = clicommon.run_command("systemctl show {} --property=LastTriggerUSecMonotonic --value".format(timer), return_cmd=True)
if out.strip() == "0":
return False
return True

def _swss_ready():
out = clicommon.run_command("systemctl show swss.service --property ActiveState --value", return_cmd=True)
if out.strip() != "active":
return False
out = clicommon.run_command("systemctl show swss.service --property ActiveEnterTimestampMonotonic --value", return_cmd=True)
swss_up_time = float(out.strip())/1000000
now = time.monotonic()
if (now - swss_up_time > 120):
return True
else:
return False

def _system_running():
out = clicommon.run_command("sudo systemctl is-system-running", return_cmd=True)
return out.strip() == "running"

def interface_is_in_vlan(vlan_member_table, interface_name):
""" Check if an interface is in a vlan """
Expand Down Expand Up @@ -777,6 +804,22 @@ def validate_mirror_session_config(config_db, session_name, dst_port, src_port,

return True

def validate_ip_mask(ctx, ip_addr):
split_ip_mask = ip_addr.split("/")
# Check if the IP address is correct or if there are leading zeros.
ip_obj = ipaddress.ip_address(split_ip_mask[0])

# Check if the mask is correct
mask_range = 33 if isinstance(ip_obj, ipaddress.IPv4Address) else 129
# If mask is not specified
if len(split_ip_mask) < 2:
return 0

if not int(split_ip_mask[1]) in range(1, mask_range):
return 0

return str(ip_obj) + '/' + str(int(split_ip_mask[1]))

def cli_sroute_to_config(ctx, command_str, strict_nh = True):
if len(command_str) < 2 or len(command_str) > 9:
ctx.fail("argument is not in pattern prefix [vrf <vrf_name>] <A.B.C.D/M> nexthop <[vrf <vrf_name>] <A.B.C.D>>|<dev <dev_name>>!")
Expand Down Expand Up @@ -1173,12 +1216,26 @@ def list_checkpoints(ctx, verbose):
@click.option('-l', '--load-sysinfo', is_flag=True, help='load system default information (mac, portmap etc) first.')
@click.option('-n', '--no_service_restart', default=False, is_flag=True, help='Do not restart docker services')
@click.option('-d', '--disable_arp_cache', default=False, is_flag=True, help='Do not cache ARP table before reloading (applies to dual ToR systems only)')
@click.option('-f', '--force', default=False, is_flag=True, help='Force config reload without system checks')
@click.argument('filename', required=False)
@clicommon.pass_db
def reload(db, filename, yes, load_sysinfo, no_service_restart, disable_arp_cache):
def reload(db, filename, yes, load_sysinfo, no_service_restart, disable_arp_cache, force):
"""Clear current configuration and import a previous saved config DB dump file.
<filename> : Names of configuration file(s) to load, separated by comma with no spaces in between
"""
if not force and not no_service_restart:
if not _system_running():
click.echo("System is not up. Retry later or use -f to avoid system checks")
return

if not _delay_timers_elapsed():
click.echo("Relevant services are not up. Retry later or use -f to avoid system checks")
return

if not _swss_ready():
click.echo("SwSS container is not ready. Retry later or use -f to avoid system checks")
return

if filename is None:
message = 'Clear current config and reload config from the default config file(s) ?'
else:
Expand Down Expand Up @@ -1292,6 +1349,9 @@ def reload(db, filename, yes, load_sysinfo, no_service_restart, disable_arp_cach
command = "{} -o migrate -n {}".format(db_migrator, namespace)
clicommon.run_command(command, display_cmd=True)

# Re-generate the environment variable in case config_db.json was edited
update_sonic_environment()

# We first run "systemctl reset-failed" to remove the "failed"
# status from all services before we attempt to restart them
if not no_service_restart:
Expand Down Expand Up @@ -1467,7 +1527,7 @@ def portchannel(ctx, namespace):

@portchannel.command('add')
@click.argument('portchannel_name', metavar='<portchannel_name>', required=True)
@click.option('--min-links', default=0, type=int)
@click.option('--min-links', default=1, type=click.IntRange(1,1024))
@click.option('--fallback', default='false')
@click.pass_context
def add_portchannel(ctx, portchannel_name, min_links, fallback):
Expand All @@ -1482,7 +1542,8 @@ def add_portchannel(ctx, portchannel_name, min_links, fallback):
ctx.fail("{} already exists!".format(portchannel_name))

fvs = {'admin_status': 'up',
'mtu': '9100'}
'mtu': '9100',
'lacp_key': 'auto'}
if min_links != 0:
fvs['min_links'] = str(min_links)
if fallback != 'false':
Expand Down Expand Up @@ -1583,6 +1644,15 @@ def add_portchannel_member(ctx, portchannel_name, port_name):
ctx.fail("Port MTU of {} is different than the {} MTU size"
.format(port_name, portchannel_name))

# Dont allow a port to be member of port channel if its TPID is not at default 0x8100
# If TPID is supported at LAG level, when member is added, the LAG's TPID is applied to the
# new member by SAI.
port_entry = db.get_entry('PORT', port_name)
if port_entry and port_entry.get(PORT_TPID) is not None:
port_tpid = port_entry.get(PORT_TPID)
if port_tpid != DEFAULT_TPID:
ctx.fail("Port TPID of {}: {} is not at default 0x8100".format(port_name, port_tpid))

db.set_entry('PORTCHANNEL_MEMBER', (portchannel_name, port_name),
{'NULL': 'NULL'})

Expand Down Expand Up @@ -3367,6 +3437,34 @@ def mtu(ctx, interface_name, interface_mtu, verbose):
command += " -vv"
clicommon.run_command(command, display_cmd=verbose)

#
# 'tpid' subcommand
#

@interface.command()
@click.pass_context
@click.argument('interface_name', metavar='<interface_name>', required=True)
@click.argument('interface_tpid', metavar='<interface_tpid>', required=True)
@click.option('-v', '--verbose', is_flag=True, help="Enable verbose output")
def tpid(ctx, interface_name, interface_tpid, verbose):
"""Set interface tpid"""
# 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!")

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

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


@interface.command()
@click.pass_context
@click.argument('interface_name', metavar='<interface_name>', required=True)
Expand Down Expand Up @@ -3434,6 +3532,10 @@ def add(ctx, interface_name, ip_addr, gw):
if '/' not in ip_addr:
ip_addr = str(net)

ip_addr = validate_ip_mask(ctx, ip_addr)
if not ip_addr:
raise ValueError('')

if interface_name == 'eth0':

# Configuring more than 1 IPv4 or more than 1 IPv6 address fails.
Expand Down Expand Up @@ -3470,7 +3572,7 @@ def add(ctx, interface_name, ip_addr, gw):
config_db.set_entry(table_name, interface_name, {"NULL": "NULL"})
config_db.set_entry(table_name, (interface_name, ip_addr), {"NULL": "NULL"})
except ValueError:
ctx.fail("'ip_addr' is not valid.")
ctx.fail("ip address or mask is not valid.")

#
# 'del' subcommand
Expand All @@ -3494,6 +3596,10 @@ def remove(ctx, interface_name, ip_addr):
net = ipaddress.ip_network(ip_addr, strict=False)
if '/' not in ip_addr:
ip_addr = str(net)

ip_addr = validate_ip_mask(ctx, ip_addr)
if not ip_addr:
raise ValueError('')

if interface_name == 'eth0':
config_db.set_entry("MGMT_INTERFACE", (interface_name, ip_addr), None)
Expand Down Expand Up @@ -3533,7 +3639,7 @@ def remove(ctx, interface_name, ip_addr):
command = "ip neigh flush dev {} {}".format(interface_name, ip_addr)
clicommon.run_command(command)
except ValueError:
ctx.fail("'ip_addr' is not valid.")
ctx.fail("ip address or mask is not valid.")


#
Expand Down
36 changes: 9 additions & 27 deletions config/muxcable.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,43 +73,25 @@ def lookup_statedb_and_update_configdb(per_npu_statedb, config_db, port, state_c
ipv6_value = get_value_for_key_in_config_tbl(config_db, port, "server_ipv6", "MUX_CABLE")

state = get_value_for_key_in_dict(muxcable_statedb_dict, port, "state", "MUX_CABLE_TABLE")
if (state == "active" and configdb_state == "active") or (state == "standby" and configdb_state == "active") or (state == "unknown" and configdb_state == "active"):
if state_cfg_val == "active":
# status is already active, so right back error
port_status_dict[port] = 'OK'
if state_cfg_val == "auto":
# display ok and write to cfgdb auto
port_status_dict[port] = 'OK'
config_db.set_entry("MUX_CABLE", port, {"state": "auto",
"server_ipv4": ipv4_value, "server_ipv6": ipv6_value})
elif state == "active" and configdb_state == "auto":
if state_cfg_val == "active":
# make the state active and write back OK
config_db.set_entry("MUX_CABLE", port, {"state": "active",
"server_ipv4": ipv4_value, "server_ipv6": ipv6_value})
port_status_dict[port] = 'OK'
if state_cfg_val == "auto":
# dont write anything to db, write OK to user
port_status_dict[port] = 'OK'

elif (state == "standby" and configdb_state == "auto") or (state == "unknown" and configdb_state == "auto"):
if state_cfg_val == "active":
# make the state active
config_db.set_entry("MUX_CABLE", port, {"state": "active",
"server_ipv4": ipv4_value, "server_ipv6": ipv6_value})
if str(state_cfg_val) == str(configdb_state):
port_status_dict[port] = 'OK'
else:
config_db.set_entry("MUX_CABLE", port, {"state": state_cfg_val,
"server_ipv4": ipv4_value, "server_ipv6": ipv6_value})
if str(state_cfg_val) == 'active' and str(state) != 'active':
port_status_dict[port] = 'INPROGRESS'
if state_cfg_val == "auto":
# dont write anything to db
else:
port_status_dict[port] = 'OK'


# 'muxcable' command ("config muxcable mode <port|all> active|auto")
@muxcable.command()
@click.argument('state', metavar='<operation_status>', required=True, type=click.Choice(["active", "auto"]))
@click.argument('state', metavar='<operation_status>', required=True, type=click.Choice(["active", "auto", "manual"]))
@click.argument('port', metavar='<port_name>', required=True, default=None)
@click.option('--json', 'json_output', required=False, is_flag=True, type=click.BOOL)
def mode(state, port, json_output):
"""Show muxcable summary information"""
"""Config muxcable mode"""

port_table_keys = {}
y_cable_asic_table_keys = {}
Expand Down
2 changes: 2 additions & 0 deletions config/plugins/mlnx.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@

# generate sniffer target file name include a time stamp.
def sniffer_filename_generate(path, filename_prefix, filename_ext):
if not os.path.exists(path):
os.makedirs(path)
time_stamp = time.strftime("%Y%m%d%H%M%S")
filename = path + filename_prefix + time_stamp + filename_ext
return filename
Expand Down
Loading

0 comments on commit 66b5873

Please sign in to comment.