Skip to content

Commit ed45412

Browse files
authored
[show][config] add support for setting and displaying switching modes on Y cable (sonic-net#1501)
Summary There is also support for new commands for muxcable/Y cable show muxcable hwmode switchmode sudo config muxcable hwmode setswitchmode manual/auto all which can basically set/display the switching modes on the cable to auto or manual using the cli What I did Also added these new commands admin@STR43-0101-0101-01LT0:~$ show muxcable hwmode switchmode Port Switching --------- ----------- Ethernet0 manual Ethernet4 manual admin@STR43-0101-0101-01LT0:/usr$ sudo config muxcable hwmode setswitchmode manual all Muxcable at port all will be changed to manual switching mode. Continue? [y/N]: y Success in switching mode on port Ethernet0 to manual Success in switching mode on port Ethernet4 to manual admin@STR43-0101-0101-01LT0:/usr$ sudo config muxcable hwmode setswitchmode auto all Muxcable at port all will be changed to auto switching mode. Continue? [y/N]: y Success in switching mode on port Ethernet0 to auto Success in switching mode on port Ethernet4 to auto Signed-off-by: vaibhav-dahiya <[email protected]>
1 parent bf46638 commit ed45412

File tree

2 files changed

+340
-3
lines changed

2 files changed

+340
-3
lines changed

config/muxcable.py

+162-1
Original file line numberDiff line numberDiff line change
@@ -429,7 +429,7 @@ def state(state, port):
429429

430430
logical_port_list_per_port = logical_port_list_for_physical_port.get(physical_port, None)
431431

432-
""" This check is required for checking whether or not this logical port is the one which is
432+
""" This check is required for checking whether or not this logical port is the one which is
433433
actually mapped to physical port and by convention it is always the first port.
434434
TODO: this should be removed with more logic to check which logical port maps to actual physical port
435435
being used"""
@@ -470,3 +470,164 @@ def state(state, port):
470470
if rc == False:
471471
click.echo("ERR: Unable to toggle one or more ports to {}".format(state))
472472
sys.exit(CONFIG_FAIL)
473+
474+
475+
@hwmode.command()
476+
@click.argument('state', metavar='<operation_status>', required=True, type=click.Choice(["auto", "manual"]))
477+
@click.argument('port', metavar='<port_name>', required=True, default=None)
478+
def setswitchmode(state, port):
479+
"""Configure the muxcable mux switching mode {auto/manual}"""
480+
481+
per_npu_statedb = {}
482+
transceiver_dict = {}
483+
484+
# Getting all front asic namespace and correspding config and state DB connector
485+
486+
namespaces = multi_asic.get_front_end_namespaces()
487+
for namespace in namespaces:
488+
asic_id = multi_asic.get_asic_index_from_namespace(namespace)
489+
per_npu_statedb[asic_id] = SonicV2Connector(use_unix_socket_path=False, namespace=namespace)
490+
per_npu_statedb[asic_id].connect(per_npu_statedb[asic_id].STATE_DB)
491+
492+
if port is not None and port != "all":
493+
click.confirm(('Muxcable at port {} will be changed to {} switching mode. Continue?'.format(port, state)), abort=True)
494+
logical_port_list = platform_sfputil_helper.get_logical_list()
495+
if port not in logical_port_list:
496+
click.echo("ERR: This is not a valid port, valid ports ({})".format(", ".join(logical_port_list)))
497+
sys.exit(CONFIG_FAIL)
498+
499+
asic_index = None
500+
if platform_sfputil is not None:
501+
asic_index = platform_sfputil_helper.get_asic_id_for_logical_port(port)
502+
if asic_index is None:
503+
# TODO this import is only for unit test purposes, and should be removed once sonic_platform_base
504+
# is fully mocked
505+
import sonic_platform_base.sonic_sfp.sfputilhelper
506+
asic_index = sonic_platform_base.sonic_sfp.sfputilhelper.SfpUtilHelper().get_asic_id_for_logical_port(port)
507+
if asic_index is None:
508+
click.echo("Got invalid asic index for port {}, cant retreive mux status".format(port))
509+
sys.exit(CONFIG_FAIL)
510+
511+
if platform_sfputil is not None:
512+
physical_port_list = platform_sfputil_helper.logical_port_name_to_physical_port_list(port)
513+
514+
if not isinstance(physical_port_list, list):
515+
click.echo(("ERR: Unable to locate physical port information for {}".format(port)))
516+
sys.exit(CONFIG_FAIL)
517+
if len(physical_port_list) != 1:
518+
click.echo("ERR: Found multiple physical ports ({}) associated with {}".format(
519+
", ".join(physical_port_list), port))
520+
sys.exit(CONFIG_FAIL)
521+
522+
transceiver_dict[asic_index] = per_npu_statedb[asic_index].get_all(
523+
per_npu_statedb[asic_index].STATE_DB, 'TRANSCEIVER_INFO|{}'.format(port))
524+
525+
vendor_value = get_value_for_key_in_dict(transceiver_dict[asic_index], port, "manufacturer", "TRANSCEIVER_INFO")
526+
model_value = get_value_for_key_in_dict(transceiver_dict[asic_index], port, "model", "TRANSCEIVER_INFO")
527+
528+
""" This check is required for checking whether or not this port is connected to a Y cable
529+
or not. The check gives a way to differentiate between non Y cable ports and Y cable ports.
530+
TODO: this should be removed once their is support for multiple vendors on Y cable"""
531+
532+
if vendor_value != VENDOR_NAME or not re.match(VENDOR_MODEL_REGEX, model_value):
533+
click.echo("ERR: Got invalid vendor value and model for port {}".format(port))
534+
sys.exit(CONFIG_FAIL)
535+
536+
physical_port = physical_port_list[0]
537+
538+
logical_port_list_for_physical_port = platform_sfputil_helper.get_physical_to_logical()
539+
540+
logical_port_list_per_port = logical_port_list_for_physical_port.get(physical_port, None)
541+
542+
""" This check is required for checking whether or not this logical port is the one which is
543+
actually mapped to physical port and by convention it is always the first port.
544+
TODO: this should be removed with more logic to check which logical port maps to actual physical port
545+
being used"""
546+
547+
if port != logical_port_list_per_port[0]:
548+
click.echo("ERR: This logical Port {} is not on a muxcable".format(port))
549+
sys.exit(CONFIG_FAIL)
550+
551+
if state == "auto":
552+
mode = sonic_y_cable.y_cable.SWITCHING_MODE_AUTO
553+
elif state == "manual":
554+
mode = sonic_y_cable.y_cable.SWITCHING_MODE_MANUAL
555+
import sonic_y_cable.y_cable
556+
result = sonic_y_cable.y_cable.set_switching_mode(physical_port, mode)
557+
if result == False:
558+
click.echo(("ERR: Unable to set switching mode for the cable port {}".format(port)))
559+
sys.exit(CONFIG_FAIL)
560+
561+
click.echo("Success in switching mode on port {} to {}".format(port, state))
562+
563+
elif port == "all" and port is not None:
564+
565+
click.confirm(('Muxcable at port {} will be changed to {} switching mode. Continue?'.format(port, state)), abort=True)
566+
logical_port_list = platform_sfputil_helper.get_logical_list()
567+
568+
rc = True
569+
for port in logical_port_list:
570+
if platform_sfputil is not None:
571+
physical_port_list = platform_sfputil_helper.logical_port_name_to_physical_port_list(port)
572+
573+
asic_index = None
574+
if platform_sfputil is not None:
575+
asic_index = platform_sfputil_helper.get_asic_id_for_logical_port(port)
576+
if asic_index is None:
577+
# TODO this import is only for unit test purposes, and should be removed once sonic_platform_base
578+
# is fully mocked
579+
import sonic_platform_base.sonic_sfp.sfputilhelper
580+
asic_index = sonic_platform_base.sonic_sfp.sfputilhelper.SfpUtilHelper().get_asic_id_for_logical_port(port)
581+
if asic_index is None:
582+
click.echo("Got invalid asic index for port {}, cant retreive mux status".format(port))
583+
584+
if not isinstance(physical_port_list, list):
585+
click.echo(("ERR: Unable to locate physical port information for {}".format(port)))
586+
continue
587+
588+
if len(physical_port_list) != 1:
589+
click.echo("ERR: Found multiple physical ports ({}) associated with {}".format(
590+
", ".join(physical_port_list), port))
591+
continue
592+
593+
transceiver_dict[asic_index] = per_npu_statedb[asic_index].get_all(
594+
per_npu_statedb[asic_index].STATE_DB, 'TRANSCEIVER_INFO|{}'.format(port))
595+
vendor_value = transceiver_dict[asic_index].get("manufacturer", None)
596+
model_value = transceiver_dict[asic_index].get("model", None)
597+
598+
""" This check is required for checking whether or not this port is connected to a Y cable
599+
or not. The check gives a way to differentiate between non Y cable ports and Y cable ports.
600+
TODO: this should be removed once their is support for multiple vendors on Y cable"""
601+
602+
if vendor_value != VENDOR_NAME or not re.match(VENDOR_MODEL_REGEX, model_value):
603+
continue
604+
605+
physical_port = physical_port_list[0]
606+
607+
logical_port_list_for_physical_port = platform_sfputil_helper.get_physical_to_logical()
608+
609+
logical_port_list_per_port = logical_port_list_for_physical_port.get(physical_port, None)
610+
611+
""" This check is required for checking whether or not this logical port is the one which is
612+
actually mapped to physical port and by convention it is always the first port.
613+
TODO: this should be removed with more logic to check which logical port maps to actual physical port
614+
being used"""
615+
616+
if port != logical_port_list_per_port[0]:
617+
continue
618+
619+
if state == "auto":
620+
mode = sonic_y_cable.y_cable.SWITCHING_MODE_AUTO
621+
elif state == "manual":
622+
mode = sonic_y_cable.y_cable.SWITCHING_MODE_MANUAL
623+
import sonic_y_cable.y_cable
624+
result = sonic_y_cable.y_cable.set_switching_mode(physical_port, mode)
625+
if result == False:
626+
rc = False
627+
click.echo("ERR: Unable to set switching mode on port {} to {}".format(port, state))
628+
629+
click.echo("Success in switching mode on port {} to {}".format(port, state))
630+
631+
if rc == False:
632+
click.echo("ERR: Unable to set switching mode one or more ports to {}".format(state))
633+
sys.exit(CONFIG_FAIL)

show/muxcable.py

+178-2
Original file line numberDiff line numberDiff line change
@@ -511,7 +511,7 @@ def muxdirection(port):
511511

512512
logical_port_list_per_port = logical_port_list_for_physical_port.get(physical_port, None)
513513

514-
""" This check is required for checking whether or not this logical port is the one which is
514+
""" This check is required for checking whether or not this logical port is the one which is
515515
actually mapped to physical port and by convention it is always the first port.
516516
TODO: this should be removed with more logic to check which logical port maps to actual physical port
517517
being used"""
@@ -594,7 +594,7 @@ def muxdirection(port):
594594

595595
logical_port_list_per_port = logical_port_list_for_physical_port.get(physical_port, None)
596596

597-
""" This check is required for checking whether or not this logical port is the one which is
597+
""" This check is required for checking whether or not this logical port is the one which is
598598
actually mapped to physical port and by convention it is always the first port.
599599
TODO: this should be removed with more logic to check which logical port maps to actual physical port
600600
being used"""
@@ -644,3 +644,179 @@ def muxdirection(port):
644644
click.echo(tabulate(body, headers=headers))
645645
if rc == False:
646646
sys.exit(EXIT_FAIL)
647+
648+
649+
@hwmode.command()
650+
@click.argument('port', metavar='<port_name>', required=False, default=None)
651+
def switchmode(port):
652+
"""Shows the current switching mode of the muxcable {auto/manual}"""
653+
654+
per_npu_statedb = {}
655+
transceiver_dict = {}
656+
657+
# Getting all front asic namespace and correspding config and state DB connector
658+
659+
namespaces = multi_asic.get_front_end_namespaces()
660+
for namespace in namespaces:
661+
asic_id = multi_asic.get_asic_index_from_namespace(namespace)
662+
per_npu_statedb[asic_id] = SonicV2Connector(use_unix_socket_path=False, namespace=namespace)
663+
per_npu_statedb[asic_id].connect(per_npu_statedb[asic_id].STATE_DB)
664+
665+
if port is not None:
666+
667+
logical_port_list = platform_sfputil_helper.get_logical_list()
668+
if port not in logical_port_list:
669+
click.echo("ERR: This is not a valid port, valid ports ({})".format(", ".join(logical_port_list)))
670+
sys.exit(EXIT_FAIL)
671+
672+
asic_index = None
673+
if platform_sfputil is not None:
674+
asic_index = platform_sfputil_helper.get_asic_id_for_logical_port(port)
675+
if asic_index is None:
676+
# TODO this import is only for unit test purposes, and should be removed once sonic_platform_base
677+
# is fully mocked
678+
import sonic_platform_base.sonic_sfp.sfputilhelper
679+
asic_index = sonic_platform_base.sonic_sfp.sfputilhelper.SfpUtilHelper().get_asic_id_for_logical_port(port)
680+
if asic_index is None:
681+
click.echo("Got invalid asic index for port {}, cant retreive mux status".format(port))
682+
sys.exit(CONFIG_FAIL)
683+
684+
transceiver_dict[asic_index] = per_npu_statedb[asic_index].get_all(
685+
per_npu_statedb[asic_index].STATE_DB, 'TRANSCEIVER_INFO|{}'.format(port))
686+
687+
vendor_value = get_value_for_key_in_dict(transceiver_dict[asic_index], port, "manufacturer", "TRANSCEIVER_INFO")
688+
model_value = get_value_for_key_in_dict(transceiver_dict[asic_index], port, "model", "TRANSCEIVER_INFO")
689+
690+
""" This check is required for checking whether or not this port is connected to a Y cable
691+
or not. The check gives a way to differentiate between non Y cable ports and Y cable ports.
692+
TODO: this should be removed once their is support for multiple vendors on Y cable"""
693+
694+
if vendor_value != VENDOR_NAME or not re.match(VENDOR_MODEL_REGEX, model_value):
695+
click.echo("ERR: Got invalid vendor value and model for port {}".format(port))
696+
sys.exit(EXIT_FAIL)
697+
698+
if platform_sfputil is not None:
699+
physical_port_list = platform_sfputil_helper.logical_port_name_to_physical_port_list(port)
700+
701+
if not isinstance(physical_port_list, list):
702+
click.echo(("ERR: Unable to locate physical port information for {}".format(port)))
703+
sys.exit(EXIT_FAIL)
704+
if len(physical_port_list) != 1:
705+
click.echo("ERR: Found multiple physical ports ({}) associated with {}".format(
706+
", ".join(physical_port_list), port))
707+
sys.exit(EXIT_FAIL)
708+
709+
physical_port = physical_port_list[0]
710+
711+
logical_port_list_for_physical_port = platform_sfputil_helper.get_physical_to_logical()
712+
713+
logical_port_list_per_port = logical_port_list_for_physical_port.get(physical_port, None)
714+
715+
""" This check is required for checking whether or not this logical port is the one which is
716+
actually mapped to physical port and by convention it is always the first port.
717+
TODO: this should be removed with more logic to check which logical port maps to actual physical port
718+
being used"""
719+
720+
if port != logical_port_list_per_port[0]:
721+
click.echo("ERR: This logical Port {} is not on a muxcable".format(port))
722+
sys.exit(EXIT_FAIL)
723+
724+
import sonic_y_cable.y_cable
725+
switching_mode = sonic_y_cable.y_cable.get_switching_mode(physical_port)
726+
if switching_mode == -1:
727+
click.echo(("ERR: Unable to get switching mode for the cable port {}".format(port)))
728+
sys.exit(EXIT_FAIL)
729+
730+
if switching_mode == sonic_y_cable.y_cable.SWITCHING_MODE_AUTO:
731+
state = "auto"
732+
elif switching_mode == sonic_y_cable.y_cable.SWITCHING_MODE_MANUAL:
733+
state = "manual"
734+
else:
735+
click.echo(("ERR: Unable to get switching state mode, port {}".format(port)))
736+
state = "unknown"
737+
headers = ['Port', 'Switching']
738+
739+
body = [[port, state]]
740+
click.echo(tabulate(body, headers=headers))
741+
742+
else:
743+
744+
logical_port_list = platform_sfputil_helper.get_logical_list()
745+
746+
rc = True
747+
body = []
748+
for port in logical_port_list:
749+
750+
temp_list = []
751+
if platform_sfputil is not None:
752+
physical_port_list = platform_sfputil_helper.logical_port_name_to_physical_port_list(port)
753+
754+
if not isinstance(physical_port_list, list):
755+
continue
756+
if len(physical_port_list) != 1:
757+
continue
758+
759+
asic_index = None
760+
if platform_sfputil is not None:
761+
asic_index = platform_sfputil_helper.get_asic_id_for_logical_port(port)
762+
if asic_index is None:
763+
# TODO this import is only for unit test purposes, and should be removed once sonic_platform_base
764+
# is fully mocked
765+
import sonic_platform_base.sonic_sfp.sfputilhelper
766+
asic_index = sonic_platform_base.sonic_sfp.sfputilhelper.SfpUtilHelper().get_asic_id_for_logical_port(port)
767+
if asic_index is None:
768+
continue
769+
770+
transceiver_dict[asic_index] = per_npu_statedb[asic_index].get_all(
771+
per_npu_statedb[asic_index].STATE_DB, 'TRANSCEIVER_INFO|{}'.format(port))
772+
vendor_value = transceiver_dict[asic_index].get("manufacturer", None)
773+
model_value = transceiver_dict[asic_index].get("model", None)
774+
775+
""" This check is required for checking whether or not this port is connected to a Y cable
776+
or not. The check gives a way to differentiate between non Y cable ports and Y cable ports.
777+
TODO: this should be removed once their is support for multiple vendors on Y cable"""
778+
779+
if vendor_value != VENDOR_NAME or not re.match(VENDOR_MODEL_REGEX, model_value):
780+
continue
781+
782+
physical_port = physical_port_list[0]
783+
logical_port_list_for_physical_port = platform_sfputil_helper.get_physical_to_logical()
784+
785+
logical_port_list_per_port = logical_port_list_for_physical_port.get(physical_port, None)
786+
787+
""" This check is required for checking whether or not this logical port is the one which is
788+
actually mapped to physical port and by convention it is always the first port.
789+
TODO: this should be removed with more logic to check which logical port maps to actual physical port
790+
being used"""
791+
792+
if port != logical_port_list_per_port[0]:
793+
continue
794+
795+
import sonic_y_cable.y_cable
796+
switching_mode = sonic_y_cable.y_cable.get_switching_mode(physical_port)
797+
if switching_mode == -1:
798+
rc = False
799+
temp_list.append(port)
800+
temp_list.append("unknown")
801+
body.append(temp_list)
802+
continue
803+
804+
if switching_mode == sonic_y_cable.y_cable.SWITCHING_MODE_AUTO:
805+
state = "auto"
806+
elif switching_mode == sonic_y_cable.y_cable.SWITCHING_MODE_MANUAL:
807+
state = "manual"
808+
else:
809+
rc = False
810+
temp_list.append(port)
811+
temp_list.append("unknown")
812+
body.append(temp_list)
813+
continue
814+
temp_list.append(port)
815+
temp_list.append(state)
816+
body.append(temp_list)
817+
818+
headers = ['Port', 'Switching']
819+
820+
click.echo(tabulate(body, headers=headers))
821+
if rc == False:
822+
sys.exit(EXIT_FAIL)

0 commit comments

Comments
 (0)