Skip to content

Commit 5e08927

Browse files
authored
[hostcfgd] Fix the state machine during eth0 default route check failure (#196)
The last del command in the following flow will fail because of a bug in MgmtIfaceCfg. During vrf add, it tries to update the default route and if the route is not present, the command will write an error log MgmtIfaceCfg is not saving the saving the state in the internal variable. This will cause problem next time and update comes. config vrf add mgmt config vrf del mgmt config vrf add mgmt config vrf del mgmt Added a UT and verified the fix Dec 18 03:57:43 sonic hostcfgd[98362]: MgmtIfaceCfg: mgmt vrf state update Dec 18 03:57:43 sonic hostcfgd[98362]: Set mgmt vrf state true Dec 18 03:57:50 sonic hostcfgd[98362]: MgmtIfaceCfg: Could not delete eth0 route Dec 18 03:58:05 sonic hostcfgd[98362]: MgmtIfaceCfg: mgmt vrf state update Dec 18 03:58:05 sonic hostcfgd[98362]: Set mgmt vrf state false
1 parent d2cc1a8 commit 5e08927

File tree

2 files changed

+29
-6
lines changed

2 files changed

+29
-6
lines changed

scripts/hostcfgd

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ def run_cmd_pipe(cmd0, cmd1, cmd2, log_err=True, raise_exception=False):
125125
check_output_pipe(cmd0, cmd1, cmd2)
126126
except Exception as err:
127127
if log_err:
128-
syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}"
128+
syslog.syslog(syslog.LOG_WARNING, "{} - failed: return code - {}, output:\n{}"
129129
.format(err.cmd, err.returncode, err.output))
130130
if raise_exception:
131131
raise
@@ -1559,6 +1559,9 @@ class MgmtIfaceCfg(object):
15591559
'services')
15601560
return
15611561

1562+
# Update cache
1563+
self.mgmt_vrf_enabled = enabled
1564+
15621565
# Remove mgmt if route
15631566
if enabled == 'true':
15641567
"""
@@ -1577,16 +1580,12 @@ class MgmtIfaceCfg(object):
15771580
cmd2 = ['wc', '-l']
15781581
run_cmd_pipe(cmd0, cmd1, cmd2, True, True)
15791582
except subprocess.CalledProcessError:
1580-
syslog.syslog(syslog.LOG_ERR, 'MgmtIfaceCfg: Could not delete '
1583+
syslog.syslog(syslog.LOG_WARNING, 'MgmtIfaceCfg: Could not delete '
15811584
'eth0 route')
15821585
return
15831586

15841587
run_cmd(["ip", "-4", "route", "del", "default", "dev", "eth0", "metric", "202"], False)
15851588

1586-
# Update cache
1587-
self.mgmt_vrf_enabled = enabled
1588-
1589-
15901589
class RSyslogCfg(object):
15911590
"""Remote syslog config daemon
15921591

tests/hostcfgd/hostcfgd_test.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import signal
55
import psutil
66
import swsscommon as swsscommon_package
7+
from subprocess import CalledProcessError
78
from sonic_py_common import device_info
89
from swsscommon import swsscommon
910
from parameterized import parameterized
@@ -324,6 +325,29 @@ def test_mgmtiface_event(self):
324325
]
325326
mocked_check_output.assert_has_calls(expected)
326327

328+
def test_mgmtvrf_route_check_failed(self):
329+
mgmtiface = hostcfgd.MgmtIfaceCfg()
330+
mgmtiface.load({}, {'mgmtVrfEnabled' : "false"})
331+
with mock.patch('hostcfgd.check_output_pipe') as mocked_check_output:
332+
with mock.patch('hostcfgd.subprocess') as mocked_subprocess:
333+
popen_mock = mock.Mock()
334+
attrs = {'communicate.return_value': ('output', 'error')}
335+
popen_mock.configure_mock(**attrs)
336+
mocked_subprocess.Popen.return_value = popen_mock
337+
mocked_subprocess.CalledProcessError = CalledProcessError
338+
# Simulate the case where there is no default route
339+
mocked_check_output.side_effect = CalledProcessError(returncode=1, cmd="", output="")
340+
341+
mgmtiface.update_mgmt_vrf({'mgmtVrfEnabled' : "true"})
342+
expected = [
343+
call(['cat', '/proc/net/route'], ['grep', '-E', r"eth0\s+00000000\s+[0-9A-Z]+\s+[0-9]+\s+[0-9]+\s+[0-9]+\s+202"], ['wc', '-l'])
344+
]
345+
mocked_check_output.assert_has_calls(expected)
346+
assert mgmtiface.mgmt_vrf_enabled == "true"
347+
348+
mgmtiface.update_mgmt_vrf({'mgmtVrfEnabled' : "false"})
349+
assert mgmtiface.mgmt_vrf_enabled == "false"
350+
327351
def test_dns_events(self):
328352
MockConfigDb.set_config_db(HOSTCFG_DAEMON_CFG_DB)
329353
MockConfigDb.event_queue = [('DNS_NAMESERVER', '1.1.1.1')]

0 commit comments

Comments
 (0)