Skip to content

Commit 7a8c7b0

Browse files
authored
Merge branch 'sonic-net:master' into frr_unified_mode_changes
2 parents 02078cd + aa52db8 commit 7a8c7b0

Some content is hidden

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

41 files changed

+2321
-261
lines changed

clear/main.py

+7
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,13 @@ def tunnelcounters():
218218
command = ["tunnelstat", "-c"]
219219
run_command(command)
220220

221+
222+
@cli.command()
223+
def srv6counters():
224+
"""Clear SRv6 counters"""
225+
command = ["srv6stat", "-c"]
226+
run_command(command)
227+
221228
#
222229
# 'clear watermarks
223230
#

config/main.py

+86-53
Original file line numberDiff line numberDiff line change
@@ -1086,8 +1086,9 @@ def validate_mirror_session_config(config_db, session_name, dst_port, src_port,
10861086
return True
10871087

10881088
def cli_sroute_to_config(ctx, command_str, strict_nh = True):
1089-
if len(command_str) < 2 or len(command_str) > 9:
1090-
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>>!")
1089+
if len(command_str) < 2 or len(command_str) > 10:
1090+
ctx.fail("argument is not in pattern prefix [vrf <vrf_name>] <A.B.C.D/M> nexthop [vrf <vrf_name>] \
1091+
<A.B.C.D>|<dev <dev_name>>|<A.B.C.D dev <dev_name>>!")
10911092
if "prefix" not in command_str:
10921093
ctx.fail("argument is incomplete, prefix not found!")
10931094
if "nexthop" not in command_str and strict_nh:
@@ -1120,36 +1121,51 @@ def cli_sroute_to_config(ctx, command_str, strict_nh = True):
11201121
ctx.fail("prefix is not in pattern!")
11211122

11221123
if nexthop_str:
1123-
if 'nexthop' in nexthop_str and 'vrf' in nexthop_str:
1124-
# nexthop_str: ['nexthop', 'vrf', Vrf-name, ip]
1125-
config_entry["nexthop"] = nexthop_str[3]
1126-
if not is_vrf_exists(config_db, nexthop_str[2]):
1127-
ctx.fail("VRF %s does not exist!"%(nexthop_str[2]))
1124+
idx = 1
1125+
if 'vrf' in nexthop_str:
1126+
# extract nexthop vrf
1127+
for vrf in nexthop_str[2].split(','):
1128+
if not is_vrf_exists(config_db, vrf):
1129+
ctx.fail("Nexthop VRF %s does not exist!" % (vrf))
11281130
config_entry["nexthop-vrf"] = nexthop_str[2]
1129-
elif 'nexthop' in nexthop_str and 'dev' in nexthop_str:
1130-
# nexthop_str: ['nexthop', 'dev', ifname]
1131-
config_entry["ifname"] = nexthop_str[2]
1132-
elif 'nexthop' in nexthop_str:
1133-
# nexthop_str: ['nexthop', ip]
1134-
config_entry["nexthop"] = nexthop_str[1]
1131+
idx = 3
1132+
1133+
if nexthop_str[idx] == 'dev':
1134+
# no nexthop IPs but interface name
1135+
config_entry["ifname"] = nexthop_str[idx + 1]
11351136
else:
1136-
ctx.fail("nexthop is not in pattern!")
1137+
# nexthop IPs present, extract them first
1138+
config_entry["nexthop"] = nexthop_str[idx]
1139+
if len(nexthop_str) > idx + 1:
1140+
if nexthop_str[idx + 1] == 'dev' and len(nexthop_str) > idx + 2:
1141+
# extract interface name
1142+
config_entry["ifname"] = nexthop_str[idx + 2]
1143+
else:
1144+
ctx.fail("nexthop is not in pattern!")
11371145

11381146
try:
11391147
ipaddress.ip_network(ip_prefix)
11401148
if 'nexthop' in config_entry:
11411149
nh_list = config_entry['nexthop'].split(',')
11421150
for nh in nh_list:
1143-
# Nexthop to portchannel
1144-
if nh.startswith('PortChannel'):
1145-
config_db = ctx.obj['config_db']
1146-
if not nh in config_db.get_keys('PORTCHANNEL'):
1147-
ctx.fail("portchannel does not exist.")
1148-
else:
1149-
ipaddress.ip_address(nh)
1151+
ipaddress.ip_address(nh)
11501152
except ValueError:
11511153
ctx.fail("ip address is not valid.")
11521154

1155+
if 'ifname' in config_entry:
1156+
ifname_list = config_entry['ifname'].split(',')
1157+
for ifname in ifname_list:
1158+
if ifname.startswith('PortChannel'):
1159+
if ifname not in config_db.get_keys('PORTCHANNEL'):
1160+
ctx.fail("portchannel does not exist.")
1161+
elif ifname.startswith("Vlan"):
1162+
if ifname not in config_db.get_keys('VLAN_INTERFACE'):
1163+
ctx.fail("vlan interface does not exist.")
1164+
elif ifname not in config_db.get_keys('INTERFACE') and \
1165+
ifname not in config_db.get_keys('VLAN_SUB_INTERFACE') and \
1166+
ifname != 'null':
1167+
ctx.fail("interface {} does not exist.".format(ifname))
1168+
11531169
if not vrf_name == "":
11541170
key = vrf_name + "|" + ip_prefix
11551171
else:
@@ -1865,11 +1881,7 @@ def reload(db, filename, yes, load_sysinfo, no_service_restart, force, file_form
18651881
return
18661882

18671883
if filename is not None and filename != "/dev/stdin":
1868-
if multi_asic.is_multi_asic():
1869-
# Multiasic has not 100% fully validated. Thus pass here.
1870-
pass
1871-
else:
1872-
config_file_yang_validation(filename)
1884+
config_file_yang_validation(filename)
18731885

18741886
#Stop services before config push
18751887
if not no_service_restart:
@@ -4624,6 +4636,11 @@ def startup(ctx, interface_name):
46244636
if sp_name in intf_fs:
46254637
config_db.mod_entry("VLAN_SUB_INTERFACE", sp_name, {"admin_status": "up"})
46264638

4639+
lo_list = config_db.get_table("LOOPBACK_INTERFACE")
4640+
for lo in lo_list:
4641+
if lo in intf_fs:
4642+
config_db.mod_entry("LOOPBACK_INTERFACE", lo, {"admin_status": "up"})
4643+
46274644
#
46284645
# 'shutdown' subcommand
46294646
#
@@ -4664,6 +4681,11 @@ def shutdown(ctx, interface_name):
46644681
if sp_name in intf_fs:
46654682
config_db.mod_entry("VLAN_SUB_INTERFACE", sp_name, {"admin_status": "down"})
46664683

4684+
lo_list = config_db.get_table("LOOPBACK_INTERFACE")
4685+
for lo in lo_list:
4686+
if lo in intf_fs:
4687+
config_db.mod_entry("LOOPBACK_INTERFACE", lo, {"admin_status": "down"})
4688+
46674689
#
46684690
# 'speed' subcommand
46694691
#
@@ -7139,53 +7161,60 @@ def route(ctx):
71397161
ctx.obj = {}
71407162
ctx.obj['config_db'] = config_db
71417163

7164+
71427165
@route.command('add', context_settings={"ignore_unknown_options": True})
7143-
@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())
7166+
@click.argument('command_str', metavar='prefix [vrf <vrf_name>] <A.B.C.D/M> nexthop [vrf <vrf_name>] \
7167+
<A.B.C.D>|<dev <dev_name>>|<A.B.C.D dev <dev_name>>', nargs=-1, type=click.Path())
71447168
@click.pass_context
71457169
def add_route(ctx, command_str):
71467170
"""Add route command"""
71477171
config_db = ctx.obj['config_db']
71487172
key, route = cli_sroute_to_config(ctx, command_str)
71497173

7150-
# If defined intf name, check if it belongs to interface
7151-
if 'ifname' in route:
7152-
if (not route['ifname'] in config_db.get_keys('VLAN_INTERFACE') and
7153-
not route['ifname'] in config_db.get_keys('INTERFACE') and
7154-
not route['ifname'] in config_db.get_keys('PORTCHANNEL_INTERFACE') and
7155-
not route['ifname'] in config_db.get_keys('VLAN_SUB_INTERFACE') and
7156-
not route['ifname'] == 'null'):
7157-
ctx.fail('interface {} doesn`t exist'.format(route['ifname']))
7158-
71597174
entry_counter = 1
71607175
if 'nexthop' in route:
71617176
entry_counter = len(route['nexthop'].split(','))
7177+
if 'ifname' in route and len(route['ifname'].split(',')) > entry_counter:
7178+
entry_counter = len(route['ifname'].split(','))
71627179

71637180
# Alignment in case the command contains several nexthop ip
71647181
for i in range(entry_counter):
7182+
# Set vrf to empty string if not defined
71657183
if 'nexthop-vrf' in route:
7166-
if i > 0:
7184+
if i >= len(route['nexthop-vrf'].split(',')):
71677185
vrf = route['nexthop-vrf'].split(',')[0]
71687186
route['nexthop-vrf'] += ',' + vrf
71697187
else:
71707188
route['nexthop-vrf'] = ''
71717189

7172-
if not 'nexthop' in route:
7190+
# Set nexthop to empty string if not defined
7191+
if 'nexthop' in route:
7192+
if i >= len(route['nexthop'].split(',')):
7193+
route['nexthop'] += ','
7194+
else:
71737195
route['nexthop'] = ''
71747196

7197+
# Set ifname to empty string if not defined
71757198
if 'ifname' in route:
7176-
if i > 0:
7199+
if i >= len(route['ifname'].split(',')):
71777200
route['ifname'] += ','
71787201
else:
71797202
route['ifname'] = ''
71807203

71817204
# Set default values for distance and blackhole because the command doesn't have such an option
71827205
if 'distance' in route:
7183-
route['distance'] += ',0'
7206+
if i >= len(route['distance'].split(',')):
7207+
route['distance'] += ',0'
71847208
else:
71857209
route['distance'] = '0'
71867210

71877211
if 'blackhole' in route:
7188-
route['blackhole'] += ',false'
7212+
if i >= len(route['blackhole'].split(',')):
7213+
# If the user configure with "ifname" as "null", set 'blackhole' attribute as true.
7214+
if route['ifname'].split(',')[i] == 'null':
7215+
route['blackhole'] += ',true'
7216+
else:
7217+
route['blackhole'] += ',false'
71897218
else:
71907219
# If the user configure with "ifname" as "null", set 'blackhole' attribute as true.
71917220
if 'ifname' in route and route['ifname'] == 'null':
@@ -7199,28 +7228,30 @@ def add_route(ctx, command_str):
71997228
# If exist update current entry
72007229
current_entry = config_db.get_entry('STATIC_ROUTE', key)
72017230

7202-
for entry in ['nexthop', 'nexthop-vrf', 'ifname', 'distance', 'blackhole']:
7203-
if not entry in current_entry:
7204-
current_entry[entry] = ''
7205-
if entry in route:
7206-
current_entry[entry] += ',' + route[entry]
7231+
for item in ['nexthop', 'nexthop-vrf', 'ifname', 'distance', 'blackhole']:
7232+
if item not in current_entry:
7233+
current_entry[item] = ''
7234+
if item in route:
7235+
current_entry[item] += ',' + route[item]
72077236
else:
7208-
current_entry[entry] += ','
7237+
current_entry[item] += ','
72097238

72107239
config_db.set_entry("STATIC_ROUTE", key, current_entry)
72117240
else:
72127241
config_db.set_entry("STATIC_ROUTE", key, route)
72137242

7243+
72147244
@route.command('del', context_settings={"ignore_unknown_options": True})
7215-
@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())
7245+
@click.argument('command_str', metavar='prefix [vrf <vrf_name>] <A.B.C.D/M> nexthop [vrf <vrf_name>] \
7246+
<A.B.C.D>|<dev <dev_name>>|<A.B.C.D dev <dev_name>>', nargs=-1, type=click.Path())
72167247
@click.pass_context
72177248
def del_route(ctx, command_str):
72187249
"""Del route command"""
72197250
config_db = ctx.obj['config_db']
72207251
key, route = cli_sroute_to_config(ctx, command_str, strict_nh=False)
72217252
keys = config_db.get_keys('STATIC_ROUTE')
7222-
prefix_tuple = tuple(key.split('|'))
7223-
if not tuple(key.split("|")) in keys and not prefix_tuple in keys:
7253+
7254+
if not tuple(key.split("|")) in keys:
72247255
ctx.fail('Route {} doesnt exist'.format(key))
72257256
else:
72267257
# If not defined nexthop or intf name remove entire route
@@ -7255,9 +7286,11 @@ def del_route(ctx, command_str):
72557286
# Create tuple from CLI argument
72567287
# config route add prefix 1.4.3.4/32 nexthop vrf Vrf-RED 20.0.0.2
72577288
# ('20.0.0.2', 'Vrf-RED', '')
7258-
for entry in ['nexthop', 'nexthop-vrf', 'ifname']:
7259-
if entry in route:
7260-
cli_tuple += (route[entry],)
7289+
for item in ['nexthop', 'nexthop-vrf', 'ifname']:
7290+
if item in route:
7291+
if ',' in route[item]:
7292+
ctx.fail('Only one nexthop can be deleted at a time')
7293+
cli_tuple += (route[item],)
72617294
else:
72627295
cli_tuple += ('',)
72637296

0 commit comments

Comments
 (0)