Skip to content

Commit b106a82

Browse files
Addition of prober_type in config and show commands for muxcable (sonic-net#3884)
New prober_type harware is being added to linkmgrd. This is config knob addition for the specific field in mUX_CABLE show command show muxcable config edited to add prober_type field
1 parent 733bdde commit b106a82

4 files changed

Lines changed: 202 additions & 34 deletions

File tree

config/muxcable.py

Lines changed: 109 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -277,14 +277,52 @@ def lookup_statedb_and_update_configdb(db, per_npu_statedb, config_db, port, sta
277277
port_status_dict[port_name] = 'OK'
278278

279279
def update_configdb_pck_loss_data(config_db, port, val):
280+
fvs = {}
280281
configdb_state = get_value_for_key_in_config_tbl(config_db, port, "state", "MUX_CABLE")
282+
fvs["state"] = configdb_state
281283
ipv4_value = get_value_for_key_in_config_tbl(config_db, port, "server_ipv4", "MUX_CABLE")
284+
fvs["server_ipv4"] = ipv4_value
282285
ipv6_value = get_value_for_key_in_config_tbl(config_db, port, "server_ipv6", "MUX_CABLE")
286+
fvs["server_ipv6"] = ipv6_value
287+
soc_ipv4_value = get_optional_value_for_key_in_config_tbl(config_db, port, "soc_ipv4", "MUX_CABLE")
288+
if soc_ipv4_value is not None:
289+
fvs["soc_ipv4"] = soc_ipv4_value
290+
cable_type = get_optional_value_for_key_in_config_tbl(config_db, port, "cable_type", "MUX_CABLE")
291+
if cable_type is not None:
292+
fvs["cable_type"] = cable_type
293+
prober_type_val = get_optional_value_for_key_in_config_tbl(config_db, port, "prober_type", "MUX_CABLE")
294+
if prober_type_val is not None:
295+
fvs["prober_type"] = prober_type_val
283296

297+
fvs["pck_loss_data_reset"] = val
284298
try:
285-
config_db.set_entry("MUX_CABLE", port, {"state": configdb_state,
286-
"server_ipv4": ipv4_value, "server_ipv6": ipv6_value,
287-
"pck_loss_data_reset": val})
299+
config_db.set_entry("MUX_CABLE", port, fvs)
300+
except ValueError as e:
301+
ctx = click.get_current_context()
302+
ctx.fail("Invalid ConfigDB. Error: {}".format(e))
303+
304+
305+
def update_configdb_prober_type(config_db, port, val):
306+
fvs = {}
307+
configdb_state = get_value_for_key_in_config_tbl(config_db, port, "state", "MUX_CABLE")
308+
fvs["state"] = configdb_state
309+
ipv4_value = get_value_for_key_in_config_tbl(config_db, port, "server_ipv4", "MUX_CABLE")
310+
fvs["server_ipv4"] = ipv4_value
311+
ipv6_value = get_value_for_key_in_config_tbl(config_db, port, "server_ipv6", "MUX_CABLE")
312+
fvs["server_ipv6"] = ipv6_value
313+
soc_ipv4_value = get_optional_value_for_key_in_config_tbl(config_db, port, "soc_ipv4", "MUX_CABLE")
314+
if soc_ipv4_value is not None:
315+
fvs["soc_ipv4"] = soc_ipv4_value
316+
cable_type = get_optional_value_for_key_in_config_tbl(config_db, port, "cable_type", "MUX_CABLE")
317+
if cable_type is not None:
318+
fvs["cable_type"] = cable_type
319+
pck_loss_data = get_optional_value_for_key_in_config_tbl(config_db, port, "pck_loss_data_reset", "MUX_CABLE")
320+
if pck_loss_data is not None:
321+
fvs["pck_loss_data_reset"] = pck_loss_data
322+
323+
fvs["prober_type"] = val
324+
try:
325+
config_db.set_entry("MUX_CABLE", port, fvs)
288326
except ValueError as e:
289327
ctx = click.get_current_context()
290328
ctx.fail("Invalid ConfigDB. Error: {}".format(e))
@@ -381,6 +419,73 @@ def mode(db, state, port, json_output):
381419
sys.exit(CONFIG_SUCCESSFUL)
382420

383421

422+
# 'muxcable' command ("config muxcable probertype hardware/software <port|all>")
423+
@muxcable.command()
424+
@click.argument('probertype', metavar='<operation_status>', required=True, type=click.Choice(["hardware", "software"]))
425+
@click.argument('port', metavar='<port_name>', required=True, default=None)
426+
@clicommon.pass_db
427+
def probertype(db, probertype, port):
428+
"""Config muxcable probertype"""
429+
430+
port = platform_sfputil_helper.get_interface_name(port, db)
431+
432+
port_table_keys = {}
433+
y_cable_asic_table_keys = {}
434+
per_npu_configdb = {}
435+
per_npu_statedb = {}
436+
437+
# Getting all front asic namespace and correspding config and state DB connector
438+
439+
namespaces = multi_asic.get_front_end_namespaces()
440+
for namespace in namespaces:
441+
asic_id = multi_asic.get_asic_index_from_namespace(namespace)
442+
# replace these with correct macros
443+
per_npu_configdb[asic_id] = ConfigDBConnector(use_unix_socket_path=True, namespace=namespace)
444+
per_npu_configdb[asic_id].connect()
445+
per_npu_statedb[asic_id] = SonicV2Connector(use_unix_socket_path=True, namespace=namespace)
446+
per_npu_statedb[asic_id].connect(per_npu_statedb[asic_id].STATE_DB)
447+
448+
port_table_keys[asic_id] = per_npu_statedb[asic_id].keys(
449+
per_npu_statedb[asic_id].STATE_DB, 'MUX_CABLE_TABLE|*')
450+
451+
if port is not None and port != "all":
452+
453+
asic_index = None
454+
if platform_sfputil is not None:
455+
asic_index = platform_sfputil.get_asic_id_for_logical_port(port)
456+
if asic_index is None:
457+
# TODO this import is only for unit test purposes, and should be removed once sonic_platform_base
458+
# is fully mocked
459+
import sonic_platform_base.sonic_sfp.sfputilhelper
460+
asic_index = sonic_platform_base.sonic_sfp.sfputilhelper.SfpUtilHelper().get_asic_id_for_logical_port(port)
461+
if asic_index is None:
462+
click.echo("Got invalid asic index for port {}, cant retreive mux status".format(port))
463+
sys.exit(CONFIG_FAIL)
464+
465+
if per_npu_statedb[asic_index] is not None:
466+
y_cable_asic_table_keys = port_table_keys[asic_index]
467+
logical_key = "MUX_CABLE_TABLE|{}".format(port)
468+
if logical_key in y_cable_asic_table_keys:
469+
update_configdb_prober_type(per_npu_configdb[asic_index], port, probertype)
470+
sys.exit(CONFIG_SUCCESSFUL)
471+
else:
472+
click.echo("this is not a valid port {} present on mux_cable".format(port))
473+
sys.exit(CONFIG_FAIL)
474+
else:
475+
click.echo("there is not a valid asic asic-{} table for this asic_index".format(asic_index))
476+
sys.exit(CONFIG_FAIL)
477+
478+
elif port == "all" and port is not None:
479+
480+
for namespace in namespaces:
481+
asic_id = multi_asic.get_asic_index_from_namespace(namespace)
482+
for key in port_table_keys[asic_id]:
483+
logical_port = key.split("|")[1]
484+
update_configdb_prober_type(per_npu_configdb[asic_id], logical_port, probertype)
485+
486+
sys.exit(CONFIG_SUCCESSFUL)
487+
488+
384489
# 'muxcable' command ("config muxcable kill-radv <enable|disable> ")
385490
@muxcable.command(short_help="Kill radv service when it is meant to be stopped, so no good-bye packet is sent for ceasing To Be an Advertising Interface")
386491
@click.argument('knob', metavar='<feature_knob>', required=True, type=click.Choice(["enable", "disable"]))
@@ -396,8 +501,7 @@ def kill_radv(db, knob):
396501
mux_lmgrd_cfg_tbl = config_db.get_table("MUX_LINKMGR")
397502
config_db.mod_entry("MUX_LINKMGR", "SERVICE_MGMT", {"kill_radv": "True" if knob == "enable" else "False"})
398503

399-
400-
#'muxcable' command ("config muxcable packetloss reset <port|all>")
504+
# 'muxcable' command ("config muxcable packetloss reset <port|all>")
401505
@muxcable.command()
402506
@click.argument('action', metavar='<action_name>', required=True, type=click.Choice(["reset"]))
403507
@click.argument('port', metavar='<port_name>', required=True, default=None)

show/muxcable.py

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -564,17 +564,26 @@ def create_table_dump_per_port_config(db ,print_data, per_npu_configdb, asic_id,
564564
cable_type = get_optional_value_for_key_in_config_tbl(per_npu_configdb[asic_id], port, "cable_type", "MUX_CABLE")
565565
if cable_type is not None:
566566
port_list.append(cable_type)
567+
else:
568+
port_list.append("")
567569
soc_ipv4_value = get_optional_value_for_key_in_config_tbl(per_npu_configdb[asic_id], port, "soc_ipv4", "MUX_CABLE")
568570
if soc_ipv4_value is not None:
569571
port_list.append(soc_ipv4_value)
570572
is_dualtor_active_active[0] = True
573+
else:
574+
port_list.append("")
571575
soc_ipv6_value = get_optional_value_for_key_in_config_tbl(per_npu_configdb[asic_id], port, "soc_ipv6", "MUX_CABLE")
572576
if soc_ipv6_value is not None:
573-
if cable_type is None:
574-
port_list.append("")
575-
if soc_ipv4_value is None:
576-
port_list.append("")
577577
port_list.append(soc_ipv6_value)
578+
else:
579+
port_list.append("")
580+
prober_type_value = get_optional_value_for_key_in_config_tbl(per_npu_configdb[asic_id],
581+
port, "prober_type", "MUX_CABLE")
582+
if prober_type_value is not None:
583+
port_list.append(prober_type_value)
584+
else:
585+
port_list.append("software")
586+
578587
print_data.append(port_list)
579588

580589

@@ -597,6 +606,11 @@ def create_json_dump_per_port_config(db, port_status_dict, per_npu_configdb, asi
597606
soc_ipv6_value = get_optional_value_for_key_in_config_tbl(per_npu_configdb[asic_id], port, "soc_ipv6", "MUX_CABLE")
598607
if soc_ipv6_value is not None:
599608
port_status_dict["MUX_CABLE"]["PORTS"][port_name]["SERVER"]["soc_ipv6"] = soc_ipv6_value
609+
prober_type_value = get_optional_value_for_key_in_config_tbl(per_npu_configdb[asic_id],
610+
port, "prober_type", "MUX_CABLE")
611+
if prober_type_value is not None:
612+
port_status_dict["MUX_CABLE"]["PORTS"][port_name]["SERVER"]["prober_type"] = prober_type_value
613+
600614

601615
def get_tunnel_route_per_port(db, port_tunnel_route, per_npu_configdb, per_npu_appl_db, per_npu_asic_db, asic_id, port):
602616

@@ -873,7 +887,7 @@ def config(db, port, json_output):
873887
print_peer_tor.append(peer_tor_data)
874888
click.echo(tabulate(print_peer_tor, headers=headers))
875889
if is_dualtor_active_active[0]:
876-
headers = ['port', 'state', 'ipv4', 'ipv6', 'cable_type', 'soc_ipv4', 'soc_ipv6']
890+
headers = ['port', 'state', 'ipv4', 'ipv6', 'cable_type', 'soc_ipv4', 'soc_ipv6', 'prober_type']
877891
else:
878892
headers = ['port', 'state', 'ipv4', 'ipv6']
879893
click.echo(tabulate(print_data, headers=headers))
@@ -925,7 +939,7 @@ def config(db, port, json_output):
925939
print_peer_tor.append(peer_tor_data)
926940
click.echo(tabulate(print_peer_tor, headers=headers))
927941
if is_dualtor_active_active[0]:
928-
headers = ['port', 'state', 'ipv4', 'ipv6', 'cable_type', 'soc_ipv4', 'soc_ipv6']
942+
headers = ['port', 'state', 'ipv4', 'ipv6', 'cable_type', 'soc_ipv4', 'soc_ipv6', 'prober_type']
929943
else:
930944
headers = ['port', 'state', 'ipv4', 'ipv6']
931945
click.echo(tabulate(print_data, headers=headers))

tests/mock_tables/config_db.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1942,12 +1942,14 @@
19421942
},
19431943
"MUX_CABLE|Ethernet4": {
19441944
"state": "auto",
1945+
"prober_type": "software",
19451946
"server_ipv4": "10.3.1.1",
19461947
"server_ipv6": "e801::46",
19471948
"soc_ipv6": "e801::47"
19481949
},
19491950
"MUX_CABLE|Ethernet8": {
19501951
"state": "active",
1952+
"prober_type": "hardware",
19511953
"server_ipv4": "10.4.1.1",
19521954
"server_ipv6": "e802::46"
19531955
},

tests/muxcable_test.py

Lines changed: 71 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -143,30 +143,30 @@
143143
SWITCH_NAME PEER_TOR
144144
------------- ----------
145145
sonic-switch 10.2.2.2
146-
port state ipv4 ipv6 cable_type soc_ipv4 soc_ipv6
147-
---------- ------- -------- -------- -------------- ---------- ----------
148-
Ethernet0 active 10.2.1.1 e800::46
149-
Ethernet4 auto 10.3.1.1 e801::46 e801::47
150-
Ethernet8 active 10.4.1.1 e802::46
151-
Ethernet12 active 10.4.1.1 e802::46
152-
Ethernet16 standby 10.1.1.1 fc00::75 active-standby
153-
Ethernet28 manual 10.1.1.1 fc00::75
154-
Ethernet32 auto 10.1.1.1 fc00::75 active-active 10.1.1.2 fc00::76
146+
port state ipv4 ipv6 cable_type soc_ipv4 soc_ipv6 prober_type
147+
---------- ------- -------- -------- -------------- ---------- ---------- -------------
148+
Ethernet0 active 10.2.1.1 e800::46 software
149+
Ethernet4 auto 10.3.1.1 e801::46 e801::47 software
150+
Ethernet8 active 10.4.1.1 e802::46 hardware
151+
Ethernet12 active 10.4.1.1 e802::46 software
152+
Ethernet16 standby 10.1.1.1 fc00::75 active-standby software
153+
Ethernet28 manual 10.1.1.1 fc00::75 software
154+
Ethernet32 auto 10.1.1.1 fc00::75 active-active 10.1.1.2 fc00::76 software
155155
"""
156156

157157
tabular_data_config_output_expected_alias = """\
158158
SWITCH_NAME PEER_TOR
159159
------------- ----------
160160
sonic-switch 10.2.2.2
161-
port state ipv4 ipv6 cable_type soc_ipv4 soc_ipv6
162-
------ ------- -------- -------- -------------- ---------- ----------
163-
etp1 active 10.2.1.1 e800::46
164-
etp2 auto 10.3.1.1 e801::46 e801::47
165-
etp3 active 10.4.1.1 e802::46
166-
etp4 active 10.4.1.1 e802::46
167-
etp5 standby 10.1.1.1 fc00::75 active-standby
168-
etp8 manual 10.1.1.1 fc00::75
169-
etp9 auto 10.1.1.1 fc00::75 active-active 10.1.1.2 fc00::76
161+
port state ipv4 ipv6 cable_type soc_ipv4 soc_ipv6 prober_type
162+
------ ------- -------- -------- -------------- ---------- ---------- -------------
163+
etp1 active 10.2.1.1 e800::46 software
164+
etp2 auto 10.3.1.1 e801::46 e801::47 software
165+
etp3 active 10.4.1.1 e802::46 hardware
166+
etp4 active 10.4.1.1 e802::46 software
167+
etp5 standby 10.1.1.1 fc00::75 active-standby software
168+
etp8 manual 10.1.1.1 fc00::75 software
169+
etp9 auto 10.1.1.1 fc00::75 active-active 10.1.1.2 fc00::76 software
170170
"""
171171

172172
json_data_status_config_output_expected = """\
@@ -186,14 +186,16 @@
186186
"SERVER": {
187187
"IPv4": "10.3.1.1",
188188
"IPv6": "e801::46",
189-
"soc_ipv6": "e801::47"
189+
"soc_ipv6": "e801::47",
190+
"prober_type": "software"
190191
}
191192
},
192193
"Ethernet8": {
193194
"STATE": "active",
194195
"SERVER": {
195196
"IPv4": "10.4.1.1",
196-
"IPv6": "e802::46"
197+
"IPv6": "e802::46",
198+
"prober_type": "hardware"
197199
}
198200
},
199201
"Ethernet12": {
@@ -250,14 +252,16 @@
250252
"SERVER": {
251253
"IPv4": "10.3.1.1",
252254
"IPv6": "e801::46",
253-
"soc_ipv6": "e801::47"
255+
"soc_ipv6": "e801::47",
256+
"prober_type": "software"
254257
}
255258
},
256259
"etp3": {
257260
"STATE": "active",
258261
"SERVER": {
259262
"IPv4": "10.4.1.1",
260-
"IPv6": "e802::46"
263+
"IPv6": "e802::46",
264+
"prober_type": "hardware"
261265
}
262266
},
263267
"etp4": {
@@ -722,7 +726,6 @@ def test_muxcable_status_config(self):
722726
db = Db()
723727

724728
result = runner.invoke(show.cli.commands["muxcable"].commands["config"], obj=db)
725-
726729
assert result.exit_code == 0
727730
assert result.output == tabular_data_config_output_expected
728731

@@ -1049,6 +1052,51 @@ def test_config_muxcable_tabular_port_with_incorrect_port(self):
10491052

10501053
assert result.exit_code == 1
10511054

1055+
def test_config_muxcable_probertype_hardware_Ethernet0(self):
1056+
runner = CliRunner()
1057+
db = Db()
1058+
1059+
with mock.patch('sonic_platform_base.sonic_sfp.sfputilhelper') as patched_util:
1060+
patched_util.SfpUtilHelper.return_value.get_asic_id_for_logical_port.return_value = 0
1061+
result = runner.invoke(config.config.commands["muxcable"].commands["probertype"], [
1062+
"hardware", "Ethernet0"], obj=db)
1063+
1064+
assert result.exit_code == 0
1065+
1066+
def test_config_muxcable_probertype_hardware_all(self):
1067+
runner = CliRunner()
1068+
db = Db()
1069+
1070+
with mock.patch('sonic_platform_base.sonic_sfp.sfputilhelper') as patched_util:
1071+
patched_util.SfpUtilHelper.return_value.get_asic_id_for_logical_port.return_value = 0
1072+
result = runner.invoke(config.config.commands["muxcable"].commands["probertype"], [
1073+
"hardware", "all"], obj=db)
1074+
1075+
assert result.exit_code == 0
1076+
1077+
def test_config_muxcable_probertype_hardware_incorrect_index(self):
1078+
runner = CliRunner()
1079+
db = Db()
1080+
1081+
with mock.patch('sonic_platform_base.sonic_sfp.sfputilhelper') as patched_util:
1082+
patched_util.SfpUtilHelper.return_value.get_asic_id_for_logical_port.return_value = 2
1083+
result = runner.invoke(config.config.commands["muxcable"].commands["probertype"], [
1084+
"hardware", "Ethernet0"], obj=db)
1085+
1086+
assert result.exit_code == 1
1087+
1088+
def test_config_muxcable_probertype_hardware_incorrect_port(self):
1089+
runner = CliRunner()
1090+
db = Db()
1091+
1092+
with mock.patch('sonic_platform_base.sonic_sfp.sfputilhelper') as patched_util:
1093+
patched_util.SfpUtilHelper.return_value.get_asic_id_for_logical_port.return_value = 0
1094+
result = runner.invoke(config.config.commands["muxcable"].commands["probertype"], [
1095+
"hardware", "Ethernet33"], obj=db)
1096+
1097+
assert result.exit_code == 1
1098+
1099+
10521100
def test_config_muxcable_packetloss_reset_Ethernet0(self):
10531101
runner = CliRunner()
10541102
db = Db()

0 commit comments

Comments
 (0)