Skip to content

Commit 5b4991f

Browse files
authored
Merge branch 'master' into icmpshow
2 parents b4232e0 + b106a82 commit 5b4991f

18 files changed

Lines changed: 535 additions & 84 deletions

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ dist/
1515
coverage.xml
1616
htmlcov/
1717

18+
# Dev tools
19+
.vscode/
20+
.idea/
21+
1822
# Ignores for sonic-utilities-data
1923
sonic-utilities-data/debian/*
2024
!sonic-utilities-data/debian/changelog

azure-pipelines.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ stages:
4040
DIFF_COVER_CHECK_THRESHOLD: 80
4141
DIFF_COVER_ENABLE: 'true'
4242
pool:
43-
vmImage: ubuntu-20.04
43+
vmImage: ubuntu-24.04
4444

4545
container:
4646
image: sonicdev-microsoft.azurecr.io:443/sonic-slave-bookworm:$(BUILD_BRANCH)

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)

doc/Command-Reference.md

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2337,7 +2337,7 @@ This command displays the state and key parameters of all BFD sessions.
23372337

23382338
- Usage:
23392339
```
2340-
show bfd summary
2340+
show bfd summary [-n <namespace>]
23412341
```
23422342
- Example:
23432343
```
@@ -2356,7 +2356,7 @@ This command displays the state and key parameters of all BFD sessions that matc
23562356

23572357
- Usage:
23582358
```
2359-
show bfd peer <peer-ip>
2359+
show bfd peer <peer-ip> [-n <namespace>]
23602360
```
23612361
- Example:
23622362
```
@@ -12004,12 +12004,13 @@ This command displays the MAC (FDB) entries either in full or partial as given b
1200412004
4) show mac -a <mac-address> - display the MACs that match a specific mac-address
1200512005
5) show mac -t <type> - display the MACs that match a specific type (static/dynamic)
1200612006
6) show mac -c - display the count of MAC addresses
12007+
7) show mac -n <namespace> - display the MACs that belong to a specific namespace
1200712008

1200812009
To show the default MAC address aging time on the switch.
1200912010

1201012011
- Usage:
1201112012
```
12012-
show mac [-v <vlan_id>] [-p <port_name>] [-a <mac_address>] [-t <type>] [-c]
12013+
show mac [-v <vlan_id>] [-p <port_name>] [-a <mac_address>] [-t <type>] [-c] [-n <namespace>]
1201312014
```
1201412015

1201512016
- Example:
@@ -12108,6 +12109,14 @@ Optionally, you can specify a VLAN ID or interface name or type or mac-address i
1210812109
admin@sonic:~$ show mac -c
1210912110
Total number of entries 18
1211012111
```
12112+
```
12113+
admin@sonic:~$ show mac -n asic0
12114+
No. Vlan MacAddress Port Type
12115+
----- ------ ----------------- ----------- -------
12116+
2 1000 50:96:23:AD:F1:65 Ethernet192 Static
12117+
2 1000 C6:C9:5E:AE:24:42 Ethernet192 Static
12118+
Total number of entries 2
12119+
```
1211112120

1211212121
**show mac aging-time**
1211312122

scripts/fdbshow

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,18 @@ import sys
3232
import os
3333
import re
3434

35+
from utilities_common.general import load_db_config
36+
3537
# mock the redis for unit test purposes #
3638
try: # pragma: no cover
37-
if os.environ["UTILITIES_UNIT_TESTING"] == "1":
39+
if os.environ["UTILITIES_UNIT_TESTING"] == "1":
3840
modules_path = os.path.join(os.path.dirname(__file__), "..")
3941
test_path = os.path.join(modules_path, "tests")
4042
sys.path.insert(0, modules_path)
4143
sys.path.insert(0, test_path)
42-
import mock_tables.dbconnector
44+
from tests.mock_tables import dbconnector
45+
46+
if os.environ["FDBSHOW_UNIT_TESTING"] == "1":
4347
mock_variants = { "1": 'asic_db',
4448
"2": 'asic_db_def_vlan',
4549
"3": 'asic_db_no_fdb',
@@ -50,23 +54,38 @@ try: # pragma: no cover
5054
mock_db_path = os.path.join(test_path, "fdbshow_input")
5155
file_name = mock_variants[os.environ["FDBSHOW_MOCK"]]
5256
jsonfile_asic = os.path.join(mock_db_path, file_name)
53-
mock_tables.dbconnector.dedicated_dbs['ASIC_DB'] = jsonfile_asic
57+
dbconnector.dedicated_dbs['ASIC_DB'] = jsonfile_asic
5458
jsonfile_counters = os.path.join(mock_db_path, 'counters_db')
55-
mock_tables.dbconnector.dedicated_dbs['COUNTERS_DB'] = jsonfile_counters
59+
dbconnector.dedicated_dbs['COUNTERS_DB'] = jsonfile_counters
60+
61+
if os.environ["UTILITIES_UNIT_TESTING_TOPOLOGY"] == "multi_asic":
62+
import tests.mock_tables.mock_multi_asic
63+
dbconnector.load_namespace_config()
5664
except KeyError: # pragma: no cover
5765
pass
5866

59-
from sonic_py_common import port_util
60-
from swsscommon.swsscommon import SonicV2Connector
67+
from sonic_py_common import port_util, multi_asic
68+
from swsscommon.swsscommon import SonicV2Connector, SonicDBConfig
6169
from tabulate import tabulate
6270

6371
class FdbShow(object):
6472

6573
HEADER = ['No.', 'Vlan', 'MacAddress', 'Port', 'Type']
6674

67-
def __init__(self):
75+
def __init__(self, namespace=None):
6876
super(FdbShow,self).__init__()
69-
self.db = SonicV2Connector(host="127.0.0.1")
77+
if namespace is not None:
78+
if not multi_asic.is_multi_asic():
79+
print("Error: Namespace is not supported in single asic")
80+
sys.exit(1)
81+
82+
if not SonicDBConfig.isGlobalInit():
83+
SonicDBConfig.load_sonic_global_db_config()
84+
85+
self.db = SonicV2Connector(use_unix_socket_path=True, namespace=namespace)
86+
else:
87+
self.db = SonicV2Connector(host="127.0.0.1")
88+
7089
self.if_name_map, \
7190
self.if_oid_map = port_util.get_interface_oid_map(self.db)
7291
self.if_br_oid_map = port_util.get_bridge_port_map(self.db)
@@ -205,10 +224,11 @@ def main():
205224
parser.add_argument('-a', '--address', type=str, help='FDB display based on specific mac address', default=None)
206225
parser.add_argument('-t', '--type', type=str, help='FDB display of specific type of mac address', default=None)
207226
parser.add_argument('-c', '--count', action='store_true', help='FDB display count of mac address')
227+
parser.add_argument('-n', '--namespace', type=str, help='Namespace name or all', default=None)
208228
args = parser.parse_args()
209229

210230
try:
211-
fdb = FdbShow()
231+
fdb = FdbShow(namespace=args.namespace)
212232
if not fdb.validate_params(args.vlan, args.port, args.address, args.type):
213233
sys.exit(1)
214234

scripts/reboot

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ function stop_pmon_service()
7777
fi
7878
systemctl stop pmon || debug "Ignore stopping pmon error $?"
7979
docker kill pmon &> /dev/null || CONTAINER_STOP_RC=$?
80-
if [[ CONTAINER_STOP_RC -ne 0 ]]; then
80+
if [[ $CONTAINER_STOP_RC -ne 0 ]]; then
8181
debug "Failed killing container pmon RC $CONTAINER_STOP_RC ."
8282
fi
8383
}
@@ -315,7 +315,7 @@ if [ -x ${WATCHDOG_UTIL} ]; then
315315
fi
316316

317317
if [[ "${PRE_SHUTDOWN}" == "yes" ]]; then
318-
echo "${DPU_MODULE_NAME} pre-shutdown steps are completed"
318+
debug "${DPU_MODULE_NAME} pre-shutdown steps are completed"
319319
exit ${EXIT_SUCCESS}
320320
fi
321321

scripts/reboot_smartswitch_helper

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,17 @@ function get_reboot_status()
4949
{
5050
local dpu_ip=$1
5151
local port=$2
52-
$(docker exec gnmi gnoi_client -target "${dpu_ip}:${port}" -logtostderr -notls -module System -rpc RebootStatus &>/dev/null)
52+
local reboot_output_file="reboot_status.txt"
53+
54+
$(docker exec gnmi gnoi_client -target "${dpu_ip}:${port}" -logtostderr -notls -module System -rpc RebootStatus | tee "$reboot_output_file" &>/dev/null)
5355
if [ $? -ne 0 ]; then
56+
rm -f "$reboot_output_file"
5457
return ${EXIT_ERROR}
5558
fi
5659
local is_reboot_active
57-
is_reboot_active=$(echo "$reboot_status" | grep "active" | awk '{print $2}')
58-
if [ "$is_reboot_active" == "false" ]; then
60+
is_reboot_active=$(cat "$reboot_output_file" | awk '/^{.*}$/' | jq -r '.active')
61+
rm -f "$reboot_output_file"
62+
if [ "$is_reboot_active" != "true" ]; then
5963
return ${EXIT_SUCCESS}
6064
fi
6165
return ${EXIT_ERROR}

0 commit comments

Comments
 (0)