Skip to content

Commit

Permalink
Merge branch 'master' of github.com:Azure/sonic-utilities into evpn_v…
Browse files Browse the repository at this point in the history
…lan_tun_cntrs
  • Loading branch information
dgsudharsan committed Oct 25, 2021
2 parents 81df07d + 8ea834b commit 45d9a47
Show file tree
Hide file tree
Showing 48 changed files with 1,740 additions and 344 deletions.
1 change: 1 addition & 0 deletions .azure-pipelines/build_and_install_module.sh
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ function build_and_install_kmodule()
echo CONFIG_MACSEC=m >> .config
echo CONFIG_NET_VENDOR_MICROSOFT=y >> .config
echo CONFIG_MICROSOFT_MANA=m >> .config
echo CONFIG_SYSTEM_REVOCATION_LIST=n >> .config
make VERSION=$VERSION PATCHLEVEL=$PATCHLEVEL SUBLEVEL=$SUBLEVEL EXTRAVERSION=-${EXTRAVERSION} LOCALVERSION=-${LOCALVERSION} modules_prepare
make M=drivers/net/team
mv drivers/net/Makefile drivers/net/Makefile.bak
Expand Down
6 changes: 6 additions & 0 deletions config/kdump.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ def kdump_disable(db):
check_kdump_table_existence(kdump_table)

db.cfgdb.mod_entry("KDUMP", "config", {"enabled": "false"})
click.echo("KDUMP configuration changes may require a reboot to take effect.")
click.echo("Save SONiC configuration using 'config save' before issuing the reboot command.")


#
Expand All @@ -56,6 +58,8 @@ def kdump_enable(db):
check_kdump_table_existence(kdump_table)

db.cfgdb.mod_entry("KDUMP", "config", {"enabled": "true"})
click.echo("KDUMP configuration changes may require a reboot to take effect.")
click.echo("Save SONiC configuration using 'config save' before issuing the reboot command.")


#
Expand All @@ -70,6 +74,8 @@ def kdump_memory(db, kdump_memory):
check_kdump_table_existence(kdump_table)

db.cfgdb.mod_entry("KDUMP", "config", {"memory": kdump_memory})
click.echo("KDUMP configuration changes may require a reboot to take effect.")
click.echo("Save SONiC configuration using 'config save' before issuing the reboot command.")


#
Expand Down
126 changes: 82 additions & 44 deletions config/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
VLAN_SUB_INTERFACE_SEPARATOR = '.'
ASIC_CONF_FILENAME = 'asic.conf'
DEFAULT_CONFIG_DB_FILE = '/etc/sonic/config_db.json'
DEFAULT_CONFIG_YANG_FILE = '/etc/sonic/config_yang.json'
NAMESPACE_PREFIX = 'asic'
INTF_KEY = "interfaces"

Expand All @@ -92,6 +93,11 @@

asic_type = None

DSCP_RANGE = click.IntRange(min=0, max=63)
TTL_RANGE = click.IntRange(min=0, max=255)
QUEUE_RANGE = click.IntRange(min=0, max=255)
GRE_TYPE_RANGE = click.IntRange(min=0, max=65535)

#
# Helper functions
#
Expand Down Expand Up @@ -287,6 +293,7 @@ def interface_name_is_valid(config_db, interface_name):
port_dict = config_db.get_table('PORT')
port_channel_dict = config_db.get_table('PORTCHANNEL')
sub_port_intf_dict = config_db.get_table('VLAN_SUB_INTERFACE')
loopback_dict = config_db.get_table('LOOPBACK_INTERFACE')

if clicommon.get_interface_naming_mode() == "alias":
interface_name = interface_alias_to_name(config_db, interface_name)
Expand All @@ -306,6 +313,10 @@ def interface_name_is_valid(config_db, interface_name):
for sub_port_intf_name in sub_port_intf_dict:
if interface_name == sub_port_intf_name:
return True
if loopback_dict:
for loopback_name in loopback_dict:
if interface_name == loopback_name:
return True
return False

def interface_name_to_alias(config_db, interface_name):
Expand Down Expand Up @@ -953,6 +964,19 @@ def cache_arp_entries():
open(restore_flag_file, 'w').close()
return success


def validate_ipv4_address(ctx, param, ip_addr):
"""Helper function to validate ipv4 address
"""
try:
ip_n = ipaddress.ip_network(ip_addr, False)
if ip_n.version != 4:
raise click.UsageError("{} is not a valid IPv4 address".format(ip_addr))
return ip_addr
except ValueError as e:
raise click.UsageError(str(e))


# This is our main entrypoint - the main 'config' command
@click.group(cls=clicommon.AbbreviationGroup, context_settings=CONTEXT_SETTINGS)
@click.pass_context
Expand Down Expand Up @@ -1245,9 +1269,10 @@ def list_checkpoints(ctx, verbose):
@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.option('-t', '--file_format', default='config_db',type=click.Choice(['config_yang', 'config_db']),show_default=True,help='specify the file format')
@click.argument('filename', required=False)
@clicommon.pass_db
def reload(db, filename, yes, load_sysinfo, no_service_restart, disable_arp_cache, force):
def reload(db, filename, yes, load_sysinfo, no_service_restart, disable_arp_cache, force, file_format):
"""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
"""
Expand All @@ -1265,9 +1290,9 @@ def reload(db, filename, yes, load_sysinfo, no_service_restart, disable_arp_cach
return

if filename is None:
message = 'Clear current config and reload config from the default config file(s) ?'
message = 'Clear current config and reload config in {} format from the default config file(s) ?'.format(file_format)
else:
message = 'Clear current config and reload config from the file(s) {} ?'.format(filename)
message = 'Clear current config and reload config in {} from the file(s) {} ?'.format(file_format, filename)

if not yes:
click.confirm(message, abort=True)
Expand All @@ -1278,7 +1303,8 @@ def reload(db, filename, yes, load_sysinfo, no_service_restart, disable_arp_cach
cfg_files = []

num_cfg_file = 1
if multi_asic.is_multi_asic():
# single config_yang file for the multi asic device
if multi_asic.is_multi_asic() and file_format == 'config_db':
num_cfg_file += num_asic

# Remove cached PG drop counters data
Expand Down Expand Up @@ -1331,14 +1357,18 @@ def reload(db, filename, yes, load_sysinfo, no_service_restart, disable_arp_cach
if cfg_files:
file = cfg_files[inst+1]
else:
if namespace is None:
file = DEFAULT_CONFIG_DB_FILE
if file_format == 'config_db':
if namespace is None:
file = DEFAULT_CONFIG_DB_FILE
else:
file = "/etc/sonic/config_db{}.json".format(inst)
else:
file = "/etc/sonic/config_db{}.json".format(inst)
file = DEFAULT_CONFIG_YANG_FILE


# Check the file exists before proceeding.
if not os.path.exists(file):
click.echo("The config_db file {} doesn't exist".format(file))
click.echo("The config file {} doesn't exist".format(file))
continue

if namespace is None:
Expand All @@ -1349,6 +1379,7 @@ def reload(db, filename, yes, load_sysinfo, no_service_restart, disable_arp_cach
config_db.connect()
client = config_db.get_redis_client(config_db.CONFIG_DB)
client.flushdb()

if load_sysinfo:
if namespace is None:
command = "{} -H -k {} --write-to-db".format(SONIC_CFGGEN_PATH, cfg_hwsku)
Expand All @@ -1359,16 +1390,23 @@ def reload(db, filename, yes, load_sysinfo, no_service_restart, disable_arp_cach
# For the database service running in linux host we use the file user gives as input
# or by default DEFAULT_CONFIG_DB_FILE. In the case of database service running in namespace,
# the default config_db<namespaceID>.json format is used.
if namespace is None:
if os.path.isfile(INIT_CFG_FILE):
command = "{} -j {} -j {} --write-to-db".format(SONIC_CFGGEN_PATH, INIT_CFG_FILE, file)
else:
command = "{} -j {} --write-to-db".format(SONIC_CFGGEN_PATH, file)

config_gen_opts = ""
if file_format == 'config_db':
config_gen_opts += ' -j {} '.format(file)
else:
if os.path.isfile(INIT_CFG_FILE):
command = "{} -j {} -j {} -n {} --write-to-db".format(SONIC_CFGGEN_PATH, INIT_CFG_FILE, file, namespace)
else:
command = "{} -j {} -n {} --write-to-db".format(SONIC_CFGGEN_PATH, file, namespace)
config_gen_opts += ' -Y {} '.format(file)

if os.path.isfile(INIT_CFG_FILE):
config_gen_opts += " -j {} ".format(INIT_CFG_FILE)

if namespace is not None:
config_gen_opts += " -n {} ".format(namespace)


command = "{sonic_cfggen} {options} --write-to-db".format(
sonic_cfggen=SONIC_CFGGEN_PATH,
options=config_gen_opts)

clicommon.run_command(command, display_cmd=True)
client.set(config_db.INIT_INDICATOR, 1)
Expand Down Expand Up @@ -1711,9 +1749,9 @@ def add_portchannel_member(ctx, portchannel_name, port_name):
# Dont allow a port to be member of port channel if its MTU does not match with portchannel
portchannel_entry = db.get_entry('PORTCHANNEL', portchannel_name)
if portchannel_entry and portchannel_entry.get(PORT_MTU) is not None :
port_entry = db.get_entry('PORT', port_name)
port_entry = db.get_entry('PORT', port_name)

if port_entry and port_entry.get(PORT_MTU) is not None:
if port_entry and port_entry.get(PORT_MTU) is not None:
port_mtu = port_entry.get(PORT_MTU)

portchannel_mtu = portchannel_entry.get(PORT_MTU)
Expand All @@ -1726,9 +1764,9 @@ def add_portchannel_member(ctx, portchannel_name, port_name):
# 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))
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 @@ -1775,12 +1813,12 @@ def mirror_session():

@mirror_session.command('add')
@click.argument('session_name', metavar='<session_name>', required=True)
@click.argument('src_ip', metavar='<src_ip>', required=True)
@click.argument('dst_ip', metavar='<dst_ip>', required=True)
@click.argument('dscp', metavar='<dscp>', required=True)
@click.argument('ttl', metavar='<ttl>', required=True)
@click.argument('gre_type', metavar='[gre_type]', required=False)
@click.argument('queue', metavar='[queue]', required=False)
@click.argument('src_ip', metavar='<src_ip>', callback=validate_ipv4_address, required=True)
@click.argument('dst_ip', metavar='<dst_ip>', callback=validate_ipv4_address, required=True)
@click.argument('dscp', metavar='<dscp>', type=DSCP_RANGE, required=True)
@click.argument('ttl', metavar='<ttl>', type=TTL_RANGE, required=True)
@click.argument('gre_type', metavar='[gre_type]', type=GRE_TYPE_RANGE, required=False)
@click.argument('queue', metavar='[queue]', type=QUEUE_RANGE, required=False)
@click.option('--policer')
def add(session_name, src_ip, dst_ip, dscp, ttl, gre_type, queue, policer):
""" Add ERSPAN mirror session.(Legacy support) """
Expand All @@ -1799,12 +1837,12 @@ def erspan(ctx):

@erspan.command('add')
@click.argument('session_name', metavar='<session_name>', required=True)
@click.argument('src_ip', metavar='<src_ip>', required=True)
@click.argument('dst_ip', metavar='<dst_ip>', required=True)
@click.argument('dscp', metavar='<dscp>', required=True)
@click.argument('ttl', metavar='<ttl>', required=True)
@click.argument('gre_type', metavar='[gre_type]', required=False)
@click.argument('queue', metavar='[queue]', required=False)
@click.argument('src_ip', metavar='<src_ip>', callback=validate_ipv4_address, required=True)
@click.argument('dst_ip', metavar='<dst_ip>', callback=validate_ipv4_address,required=True)
@click.argument('dscp', metavar='<dscp>', type=DSCP_RANGE, required=True)
@click.argument('ttl', metavar='<ttl>', type=TTL_RANGE, required=True)
@click.argument('gre_type', metavar='[gre_type]', type=GRE_TYPE_RANGE, required=False)
@click.argument('queue', metavar='[queue]', type=QUEUE_RANGE, required=False)
@click.argument('src_port', metavar='[src_port]', required=False)
@click.argument('direction', metavar='[direction]', required=False)
@click.option('--policer')
Expand Down Expand Up @@ -1877,7 +1915,7 @@ def span(ctx):
@click.argument('dst_port', metavar='<dst_port>', required=True)
@click.argument('src_port', metavar='[src_port]', required=False)
@click.argument('direction', metavar='[direction]', required=False)
@click.argument('queue', metavar='[queue]', required=False)
@click.argument('queue', metavar='[queue]', type=QUEUE_RANGE, required=False)
@click.option('--policer')
def add(session_name, dst_port, src_port, direction, queue, policer):
""" Add SPAN mirror session """
Expand Down Expand Up @@ -3132,10 +3170,10 @@ def startup(ctx, interface_name):

intf_fs = parse_interface_in_filter(interface_name)
if len(intf_fs) > 1 and multi_asic.is_multi_asic():
ctx.fail("Interface range not supported in multi-asic platforms !!")
ctx.fail("Interface range not supported in multi-asic platforms !!")

if len(intf_fs) == 1 and interface_name_is_valid(config_db, interface_name) is False:
ctx.fail("Interface name is invalid. Please enter a valid interface name!!")
ctx.fail("Interface name is invalid. Please enter a valid interface name!!")

log.log_info("'interface startup {}' executing...".format(interface_name))
port_dict = config_db.get_table('PORT')
Expand Down Expand Up @@ -3173,7 +3211,7 @@ def shutdown(ctx, interface_name):

intf_fs = parse_interface_in_filter(interface_name)
if len(intf_fs) > 1 and multi_asic.is_multi_asic():
ctx.fail("Interface range not supported in multi-asic platforms !!")
ctx.fail("Interface range not supported in multi-asic platforms !!")

if len(intf_fs) == 1 and interface_name_is_valid(config_db, interface_name) is False:
ctx.fail("Interface name is invalid. Please enter a valid interface name!!")
Expand Down Expand Up @@ -3609,8 +3647,8 @@ def add(ctx, interface_name, ip_addr, gw):
# changing it to a router port
vlan_member_table = config_db.get_table('VLAN_MEMBER')
if (interface_is_in_vlan(vlan_member_table, interface_name)):
click.echo("Interface {} is a member of vlan\nAborting!".format(interface_name))
return
click.echo("Interface {} is a member of vlan\nAborting!".format(interface_name))
return

try:
net = ipaddress.ip_network(ip_addr, strict=False)
Expand Down Expand Up @@ -4043,7 +4081,7 @@ def add(ctx, interface_name):
if interface_name is None:
ctx.fail("'interface_name' is None!")

table_name = get_interface_table_name(interface_name)
table_name = get_interface_table_name(interface_name)
if not clicommon.is_interface_in_config_db(config_db, interface_name):
ctx.fail('interface {} doesn`t exist'.format(interface_name))
if table_name == "":
Expand All @@ -4065,7 +4103,7 @@ def remove(ctx, interface_name):
if interface_name is None:
ctx.fail("'interface_name' is None!")

table_name = get_interface_table_name(interface_name)
table_name = get_interface_table_name(interface_name)
if not clicommon.is_interface_in_config_db(config_db, interface_name):
ctx.fail('interface {} doesn`t exist'.format(interface_name))
if table_name == "":
Expand Down Expand Up @@ -4383,7 +4421,7 @@ def route(ctx):
ctx.obj = {}
ctx.obj['config_db'] = config_db

@route.command('add', context_settings={"ignore_unknown_options":True})
@route.command('add', context_settings={"ignore_unknown_options": True})
@click.argument('command_str', metavar='prefix [vrf <vrf_name>] <A.B.C.D/M> nexthop <[vrf <vrf_name>] <A.B.C.D>>|<dev <dev_name>>', nargs=-1, type=click.Path())
@click.pass_context
def add_route(ctx, command_str):
Expand Down Expand Up @@ -4454,7 +4492,7 @@ def add_route(ctx, command_str):
else:
config_db.set_entry("STATIC_ROUTE", key, route)

@route.command('del', context_settings={"ignore_unknown_options":True})
@route.command('del', context_settings={"ignore_unknown_options": True})
@click.argument('command_str', metavar='prefix [vrf <vrf_name>] <A.B.C.D/M> nexthop <[vrf <vrf_name>] <A.B.C.D>>|<dev <dev_name>>', nargs=-1, type=click.Path())
@click.pass_context
def del_route(ctx, command_str):
Expand Down
2 changes: 1 addition & 1 deletion config/mclag.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def mclag_ka_session_dep_check(ka, session_tmout):
"""Check if the MCLAG Keepalive timer and session timeout values are multiples of each other and keepalive is < session timeout value
"""
if not session_tmout >= ( 3 * ka):
return False, "MCLAG Keepalive:{} Session_timeout:{} values not satisfying session_timeout >= (3 * KA) ".format(session_tmout, ka)
return False, "MCLAG Keepalive:{} Session_timeout:{} values not satisfying session_timeout >= (3 * KA) ".format(ka, session_tmout)

if session_tmout % ka:
return False, "MCLAG keepalive:{} Session_timeout:{} Values not satisfying session_timeout should be a multiple of KA".format(ka, session_tmout)
Expand Down
Loading

0 comments on commit 45d9a47

Please sign in to comment.