Skip to content

Commit be6c5a1

Browse files
yaqiangzKAVITHA RAMALINGAM
authored andcommitted
[smart_switch][dhcp_server] Fix query dhcp lease get unknown in smart switch by Cli (sonic-net#20642)
Why I did it In smart switch, there is an issue that Cli query dhcp lease got unknow interface due to dpu fdb hasn't present in STATE_DB FDB_TABLE. Issue: sonic-net#20155 How I did it Query bridge fdb if there is no fdb record in STATE_DB How to verify it UT passed
1 parent 4a859f3 commit be6c5a1

File tree

4 files changed

+62
-28
lines changed

4 files changed

+62
-28
lines changed

dockers/docker-dhcp-server/cli-plugin-tests/mock_state_db.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@
1414
"lease_end": "1677641481",
1515
"ip": "192.168.0.3"
1616
},
17+
"DHCP_SERVER_IPV4_LEASE|bridge-midplane|10:70:fd:b6:13:03": {
18+
"lease_start": "1677640581",
19+
"lease_end": "1677641481",
20+
"ip": "192.168.0.4"
21+
},
1722
"DHCP_SERVER_IPV4_SERVER_IP|eth0": {
1823
"ip": "240.127.1.2"
1924
},
Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,2 @@
11
[pytest]
2-
addopts = --cov-config=.coveragerc --cov --cov-report html --cov-report term --cov-report xml --junitxml=test-results.xml -vv
3-
2+
addopts = --cov=/sonic/dockers/docker-dhcp-server/cli --cov-config=.coveragerc --cov-report html --cov-report term --cov-report term-missing --cov-report xml --junitxml=test-results.xml -vv

dockers/docker-dhcp-server/cli-plugin-tests/test_show_dhcp_server.py

Lines changed: 49 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -9,39 +9,41 @@
99
sys.path.append('../cli/show/plugins/')
1010
import show_dhcp_server
1111

12+
BRIDGE_FDB_MAC = {
13+
"10:70:fd:b6:13:03": "dpu0"
14+
}
1215

13-
class TestShowDHCPServer(object):
16+
17+
class TestShowDHCPServerLease(object):
1418
def test_plugin_registration(self):
1519
cli = mock.MagicMock()
1620
show_dhcp_server.register(cli)
1721

18-
@pytest.mark.parametrize("state", ["disabled", "enabled"])
19-
def test_show_dhcp_server_feature_state_checking(self, mock_db, state):
20-
runner = CliRunner()
21-
db = clicommon.Db()
22-
db.db = mock_db
23-
mock_db.set("CONFIG_DB", "FEATURE|dhcp_server", "state", state)
24-
result = runner.invoke(show_dhcp_server.dhcp_server, obj=db)
25-
if state == "disabled":
26-
assert result.exit_code == 2, "exit code: {}, Exception: {}, Traceback: {}".format(result.exit_code, result.exception, result.exc_info)
27-
assert "Feature dhcp_server is not enabled" in result.output
28-
elif state == "enabled":
29-
assert result.exit_code == 0, "exit code: {}, Exception: {}, Traceback: {}".format(result.exit_code, result.exception, result.exc_info)
30-
assert "Usage: dhcp_server [OPTIONS] COMMAND [ARGS]" in result.output
31-
else:
32-
assert False
22+
@pytest.fixture(scope="class", autouse=True)
23+
def mock_run_cmd_fixture(self):
24+
def mock_run_command(cmd, return_cmd=False, shell=False):
25+
splits = cmd.split("sudo bridge fdb show | grep ")
26+
if len(splits) == 2 and splits[1] in BRIDGE_FDB_MAC:
27+
return ("{} dev {} master bridge-midplane".format(splits[1], BRIDGE_FDB_MAC[splits[1]]), 0)
28+
else:
29+
return ("", 0)
30+
31+
with mock.patch("utilities_common.cli.run_command", side_effect=mock_run_command):
32+
yield
3333

3434
def test_show_dhcp_server_ipv4_lease_without_dhcpintf(self, mock_db):
3535
expected_stdout = """\
36-
+---------------------+-------------------+-------------+---------------------+---------------------+
37-
| Interface | MAC Address | IP | Lease Start | Lease End |
38-
+=====================+===================+=============+=====================+=====================+
39-
| Vlan1000|Ethernet10 | 10:70:fd:b6:13:00 | 192.168.0.1 | 2023-03-01 03:16:21 | 2023-03-01 03:31:21 |
40-
+---------------------+-------------------+-------------+---------------------+---------------------+
41-
| Vlan1000|Ethernet11 | 10:70:fd:b6:13:01 | 192.168.0.2 | 2023-03-01 03:16:21 | 2023-03-01 03:31:21 |
42-
+---------------------+-------------------+-------------+---------------------+---------------------+
43-
| Vlan1001|<Unknown> | 10:70:fd:b6:13:02 | 192.168.0.3 | 2023-03-01 03:16:21 | 2023-03-01 03:31:21 |
44-
+---------------------+-------------------+-------------+---------------------+---------------------+
36+
+----------------------+-------------------+-------------+---------------------+---------------------+
37+
| Interface | MAC Address | IP | Lease Start | Lease End |
38+
+======================+===================+=============+=====================+=====================+
39+
| Vlan1000|Ethernet10 | 10:70:fd:b6:13:00 | 192.168.0.1 | 2023-03-01 03:16:21 | 2023-03-01 03:31:21 |
40+
+----------------------+-------------------+-------------+---------------------+---------------------+
41+
| Vlan1000|Ethernet11 | 10:70:fd:b6:13:01 | 192.168.0.2 | 2023-03-01 03:16:21 | 2023-03-01 03:31:21 |
42+
+----------------------+-------------------+-------------+---------------------+---------------------+
43+
| Vlan1001|<Unknown> | 10:70:fd:b6:13:02 | 192.168.0.3 | 2023-03-01 03:16:21 | 2023-03-01 03:31:21 |
44+
+----------------------+-------------------+-------------+---------------------+---------------------+
45+
| bridge-midplane|dpu0 | 10:70:fd:b6:13:03 | 192.168.0.4 | 2023-03-01 03:16:21 | 2023-03-01 03:31:21 |
46+
+----------------------+-------------------+-------------+---------------------+---------------------+
4547
"""
4648
runner = CliRunner()
4749
db = clicommon.Db()
@@ -82,6 +84,28 @@ def test_show_dhcp_server_ipv4_lease_client_not_in_fdb(self, mock_db):
8284
assert result.exit_code == 0, "exit code: {}, Exception: {}, Traceback: {}".format(result.exit_code, result.exception, result.exc_info)
8385
assert result.stdout == expected_stdout
8486

87+
88+
class TestShowDHCPServer(object):
89+
def test_plugin_registration(self):
90+
cli = mock.MagicMock()
91+
show_dhcp_server.register(cli)
92+
93+
@pytest.mark.parametrize("state", ["disabled", "enabled"])
94+
def test_show_dhcp_server_feature_state_checking(self, mock_db, state):
95+
runner = CliRunner()
96+
db = clicommon.Db()
97+
db.db = mock_db
98+
mock_db.set("CONFIG_DB", "FEATURE|dhcp_server", "state", state)
99+
result = runner.invoke(show_dhcp_server.dhcp_server, obj=db)
100+
if state == "disabled":
101+
assert result.exit_code == 2, "exit code: {}, Exception: {}, Traceback: {}".format(result.exit_code, result.exception, result.exc_info)
102+
assert "Feature dhcp_server is not enabled" in result.output
103+
elif state == "enabled":
104+
assert result.exit_code == 0, "exit code: {}, Exception: {}, Traceback: {}".format(result.exit_code, result.exception, result.exc_info)
105+
assert "Usage: dhcp_server [OPTIONS] COMMAND [ARGS]" in result.output
106+
else:
107+
assert False
108+
85109
def test_show_dhcp_server_ipv4_range_without_name(self, mock_db):
86110
expected_stdout = """\
87111
+---------+------------+------------+------------------------+

dockers/docker-dhcp-server/cli/show/plugins/show_dhcp_server.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import click
2+
import re
23
from tabulate import tabulate
34
import utilities_common.cli as clicommon
45

56

67
import ipaddress
78
from datetime import datetime
89
import fnmatch
9-
import re
1010

1111

1212
def ts_to_str(ts):
@@ -43,6 +43,12 @@ def lease(db, dhcp_interface):
4343
entry = dbconn.get_all("STATE_DB", key)
4444
interface, mac = key.split("|")[1:]
4545
port = dbconn.get("STATE_DB", "FDB_TABLE|" + interface + ":" + mac, "port")
46+
if not port:
47+
# Smart switch sample: aa:bb:cc:dd:ee:ff dev dpu0 master bridge-midplane
48+
(out, _) = clicommon.run_command("sudo bridge fdb show | grep {}".format(mac), return_cmd=True, shell=True)
49+
match = re.match(r'([0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2} dev (.*) master (.*)', out)
50+
if match and match.group(3).strip() == interface:
51+
port = match.group(2).strip()
4652
if not port:
4753
port = "<Unknown>"
4854
table.append([interface + "|" + port, mac, entry["ip"], ts_to_str(entry["lease_start"]), ts_to_str(entry["lease_end"])])

0 commit comments

Comments
 (0)