Skip to content

Commit d6d866f

Browse files
authored
show command for icmp echo offload sessions (#3889)
What I did Added show command to display icmp echo offload sessions How I did it added show utility icmp.py How to verify it added pytests to verify
1 parent 1b3498c commit d6d866f

File tree

6 files changed

+286
-0
lines changed

6 files changed

+286
-0
lines changed

show/icmp.py

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
#!/usr/bin/env python3
2+
3+
import click
4+
import utilities_common.cli as clicommon
5+
import socket
6+
7+
from swsscommon.swsscommon import SonicV2Connector
8+
from sonic_py_common import multi_asic
9+
from tabulate import tabulate
10+
11+
12+
class IcmpShow:
13+
def __init__(self, click):
14+
self.click = click
15+
namespaces = multi_asic.get_front_end_namespaces()
16+
self.asic_ids = []
17+
self.per_npu_statedb = {}
18+
self.icmp_echo_table_keys = {}
19+
self.ctx = self.click.get_current_context()
20+
for namespace in namespaces:
21+
asic_id = multi_asic.get_asic_index_from_namespace(namespace)
22+
self.asic_ids.append(asic_id)
23+
self.per_npu_statedb[asic_id] = SonicV2Connector(use_unix_socket_path=False, namespace=namespace)
24+
try:
25+
self.per_npu_statedb[asic_id].connect(self.per_npu_statedb[asic_id].STATE_DB)
26+
self.icmp_echo_table_keys[asic_id] = sorted(
27+
self.per_npu_statedb[asic_id].keys(self.per_npu_statedb[asic_id].STATE_DB,
28+
'ICMP_ECHO_SESSION_TABLE|*'))
29+
except (socket.error, IOError) as e:
30+
self.ctx.fail("Socket error in connecting with ICMP_ECHO_SESSION_TABLE: {}".format(str(e)))
31+
except (KeyError, ValueError) as e:
32+
self.ctx.fail("Error getting keys from ICMP_ECHO_SESSION_TABLE: {}".format(str(e)))
33+
34+
def get_icmp_echo_entry(self, asic_id, key):
35+
"""Show icmp echo session entry from state db."""
36+
state_db = self.per_npu_statedb[asic_id]
37+
tbl_dict = state_db.get_all(state_db.STATE_DB, key)
38+
if tbl_dict:
39+
# Prepare data for tabulate
40+
fields = {
41+
"key": key.removeprefix("ICMP_ECHO_SESSION_TABLE|"),
42+
"state": None,
43+
"dst_ip": None,
44+
"tx_interval": None,
45+
"rx_interval": None,
46+
"hw_lookup": None,
47+
"session_cookie": None
48+
}
49+
for f in tbl_dict:
50+
if f in fields:
51+
fields[f] = tbl_dict[f]
52+
return [fields["key"], fields["dst_ip"], fields["tx_interval"], fields["rx_interval"], fields["hw_lookup"],
53+
fields["session_cookie"], fields["state"]]
54+
else:
55+
return None
56+
57+
def show_icmp_sessions(self, key):
58+
table_data = []
59+
for asic_id in self.asic_ids:
60+
keys = []
61+
if key is None:
62+
keys = self.icmp_echo_table_keys[asic_id]
63+
else:
64+
keys.append("ICMP_ECHO_SESSION_TABLE|" + key.replace(":", "|"))
65+
66+
for k in keys:
67+
entry = self.get_icmp_echo_entry(asic_id, k)
68+
if entry:
69+
table_data.append(entry)
70+
71+
if table_data:
72+
headers = ["Key", "Dst IP", "Tx Interval", "Rx Interval", "HW lookup", "Cookie", "State"]
73+
click.echo(tabulate(table_data, headers=headers))
74+
else:
75+
click.echo("Keys not found in ICMP_ECHO_SESSION_TABLE")
76+
77+
def show_summary(self):
78+
total_sessions = 0
79+
total_up = 0
80+
total_rx = 0
81+
for asic_id in self.asic_ids:
82+
keys = self.icmp_echo_table_keys[asic_id]
83+
84+
for k in keys:
85+
if 'RX' in k:
86+
total_rx = total_rx + 1
87+
entry = self.get_icmp_echo_entry(asic_id, k)
88+
total_sessions = total_sessions + 1
89+
if entry and entry[6] == "Up":
90+
total_up = total_up + 1
91+
92+
self.click.echo("Total Sessions: {}".format(total_sessions))
93+
self.click.echo("Up sessions: {}".format(total_up))
94+
self.click.echo("RX sessions: {}".format(total_rx))
95+
96+
97+
@click.group(cls=clicommon.AliasedGroup)
98+
def icmp():
99+
"""Show icmp-offload information"""
100+
pass
101+
102+
103+
@icmp.command()
104+
@click.argument('key', required=False)
105+
def sessions(key):
106+
s_icmp = IcmpShow(click)
107+
s_icmp.show_icmp_sessions(key)
108+
109+
110+
@icmp.command()
111+
def summary():
112+
s_icmp = IcmpShow(click)
113+
s_icmp.show_summary()

show/main.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
from . import bgp_cli
7070
from . import stp
7171
from . import srv6
72+
from . import icmp
7273

7374
# Global Variables
7475
PLATFORM_JSON = 'platform.json'
@@ -322,6 +323,7 @@ def cli(ctx):
322323
cli.add_command(dns.dns)
323324
cli.add_command(stp.spanning_tree)
324325
cli.add_command(srv6.srv6)
326+
cli.add_command(icmp.icmp)
325327

326328
# syslog module
327329
cli.add_command(syslog.syslog)

tests/icmp_test.py

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import os
2+
3+
from click.testing import CliRunner
4+
from utilities_common.db import Db
5+
6+
import show.main as show
7+
8+
9+
tabular_session_status_output_expected = """\
10+
Key Dst IP Tx Interval Rx Interval HW lookup Cookie State
11+
------------------------------------- ------------ ------------- ------------- ----------- ---------- -------
12+
default|Ethernet0|0x4eb39592|RX 192.168.0.3 0 300 false 0x58767e7a Up
13+
default|Ethernet128|0x23ffb930|NORMAL 192.168.0.31 100 300 false 0x58767e7a Down
14+
default|Ethernet152|0x39e05375|NORMAL 192.168.0.37 100 300 false 0x58767e7a Up
15+
default|Ethernet8|0x69f578f5|NORMAL 192.168.0.5 100 300 false 0x58767e7a Up
16+
"""
17+
18+
session_summary_output_expected = """\
19+
Total Sessions: 4
20+
Up sessions: 3
21+
RX sessions: 1
22+
"""
23+
24+
tabular_session_key_status_output_expected = """\
25+
Key Dst IP Tx Interval Rx Interval HW lookup Cookie State
26+
------------------------------- ----------- ------------- ------------- ----------- ---------- -------
27+
default|Ethernet0|0x4eb39592|RX 192.168.0.3 0 300 false 0x58767e7a Up
28+
"""
29+
30+
31+
class TestIcmpSession(object):
32+
@classmethod
33+
def setup_class(cls):
34+
os.environ['UTILITIES_UNIT_TESTING'] = "1"
35+
print("SETUP")
36+
37+
def test_icmpecho_summary(self):
38+
runner = CliRunner()
39+
db = Db()
40+
41+
result = runner.invoke(show.cli.commands["icmp"].commands["summary"], obj=db)
42+
43+
assert result.exit_code == 0
44+
assert result.output == session_summary_output_expected
45+
46+
def test_icmpecho_sessions(self):
47+
runner = CliRunner()
48+
db = Db()
49+
result = runner.invoke(show.cli.commands["icmp"].commands["sessions"], obj=db)
50+
print(result.exit_code)
51+
print(result.output)
52+
53+
assert result.exit_code == 0
54+
assert result.output == tabular_session_status_output_expected
55+
56+
def test_icmpecho_key_sessions(self):
57+
runner = CliRunner()
58+
db = Db()
59+
result = runner.invoke(show.cli.commands["icmp"].commands["sessions"],
60+
"default|Ethernet0|0x4eb39592|RX", obj=db)
61+
print(result.exit_code)
62+
print(result.output)
63+
64+
assert result.exit_code == 0
65+
assert result.output == tabular_session_key_status_output_expected
66+
67+
@classmethod
68+
def teardown_class(cls):
69+
os.environ['UTILITIES_UNIT_TESTING'] = "0"
70+
print("TEARDOWN")

tests/mock_tables/asic0/state_db.json

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,37 @@
340340
"PORT_CAPACITY_TABLE|PORT_CAPACITY_DATA" : {
341341
"capacity": "80000"
342342
},
343+
"ICMP_ECHO_SESSION_TABLE|default|Ethernet8|0x69f578f5|NORMAL" : {
344+
"dst_ip": "192.168.0.5",
345+
"hw_lookup": "false",
346+
"rx_interval": "300",
347+
"session_cookie": "0x58767e7a",
348+
"session_guid": "0x69f578f5",
349+
"src_ip": "10.1.0.36",
350+
"state": "Up",
351+
"tx_interval": "100"
352+
},
353+
"ICMP_ECHO_SESSION_TABLE|default|Ethernet0|0x4eb39592|RX" : {
354+
"dst_ip": "192.168.0.3",
355+
"hw_lookup": "false",
356+
"rx_interval": "300",
357+
"session_cookie": "0x58767e7a",
358+
"session_guid": "0x4eb39592",
359+
"src_ip": "10.1.0.36",
360+
"state": "Up",
361+
"tx_interval": "0"
362+
},
363+
"ICMP_ECHO_SESSION_TABLE|default|Ethernet128|0x23ffb930|NORMAL" : {
364+
"dst_ip": "192.168.0.31",
365+
"hw_lookup": "false",
366+
"rx_interval": "300",
367+
"session_cookie": "0x58767e7a",
368+
"session_guid": "0x23ffb930",
369+
"src_ip": "10.1.0.36",
370+
"state": "Down",
371+
"tx_interval": "100"
372+
373+
},
343374
"BFD_SESSION_TABLE|default|default|10.0.1.1": {
344375
"state": "DOWN",
345376
"type": "async_active",

tests/mock_tables/asic1/state_db.json

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,5 +280,35 @@
280280
},
281281
"PORT_CAPACITY_TABLE|PORT_CAPACITY_DATA" : {
282282
"capacity": "80000"
283+
},
284+
"ICMP_ECHO_SESSION_TABLE|default|Ethernet8|0x69f578f5|NORMAL" : {
285+
"dst_ip": "192.168.0.5",
286+
"hw_lookup": "false",
287+
"rx_interval": "300",
288+
"session_cookie": "0x58767e7a",
289+
"session_guid": "0x69f578f5",
290+
"src_ip": "10.1.0.36",
291+
"state": "Up",
292+
"tx_interval": "100"
293+
},
294+
"ICMP_ECHO_SESSION_TABLE|default|Ethernet0|0x4eb39592|RX" : {
295+
"dst_ip": "192.168.0.3",
296+
"hw_lookup": "false",
297+
"rx_interval": "300",
298+
"session_cookie": "0x58767e7a",
299+
"session_guid": "0x4eb39592",
300+
"src_ip": "10.1.0.36",
301+
"state": "Up",
302+
"tx_interval": "0"
303+
},
304+
"ICMP_ECHO_SESSION_TABLE|default|Ethernet128|0x23ffb930|NORMAL" : {
305+
"dst_ip": "192.168.0.31",
306+
"hw_lookup": "false",
307+
"rx_interval": "300",
308+
"session_cookie": "0x58767e7a",
309+
"session_guid": "0x23ffb930",
310+
"src_ip": "10.1.0.36",
311+
"state": "Down",
312+
"tx_interval": "100"
283313
}
284314
}

tests/mock_tables/state_db.json

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1777,5 +1777,45 @@
17771777
"mac_remote_fault_time": "",
17781778
"mac_local_fault_count": "0",
17791779
"mac_local_fault_time": ""
1780+
},
1781+
"ICMP_ECHO_SESSION_TABLE|default|Ethernet8|0x69f578f5|NORMAL" : {
1782+
"dst_ip": "192.168.0.5",
1783+
"hw_lookup": "false",
1784+
"rx_interval": "300",
1785+
"session_cookie": "0x58767e7a",
1786+
"session_guid": "0x69f578f5",
1787+
"src_ip": "10.1.0.36",
1788+
"state": "Up",
1789+
"tx_interval": "100"
1790+
},
1791+
"ICMP_ECHO_SESSION_TABLE|default|Ethernet0|0x4eb39592|RX" : {
1792+
"dst_ip": "192.168.0.3",
1793+
"hw_lookup": "false",
1794+
"rx_interval": "300",
1795+
"session_cookie": "0x58767e7a",
1796+
"session_guid": "0x4eb39592",
1797+
"src_ip": "10.1.0.36",
1798+
"state": "Up",
1799+
"tx_interval": "0"
1800+
},
1801+
"ICMP_ECHO_SESSION_TABLE|default|Ethernet128|0x23ffb930|NORMAL" : {
1802+
"dst_ip": "192.168.0.31",
1803+
"hw_lookup": "false",
1804+
"rx_interval": "300",
1805+
"session_cookie": "0x58767e7a",
1806+
"session_guid": "0x23ffb930",
1807+
"src_ip": "10.1.0.36",
1808+
"state": "Down",
1809+
"tx_interval": "100"
1810+
},
1811+
"ICMP_ECHO_SESSION_TABLE|default|Ethernet152|0x39e05375|NORMAL" : {
1812+
"dst_ip": "192.168.0.37",
1813+
"hw_lookup": "false",
1814+
"rx_interval": "300",
1815+
"session_cookie": "0x58767e7a",
1816+
"session_guid": "0x39e05375",
1817+
"src_ip": "10.1.0.36",
1818+
"state": "Up",
1819+
"tx_interval": "100"
17801820
}
17811821
}

0 commit comments

Comments
 (0)