diff --git a/ironic_python_agent/agent.py b/ironic_python_agent/agent.py index c3d81e1bf..ce313a7be 100644 --- a/ironic_python_agent/agent.py +++ b/ironic_python_agent/agent.py @@ -21,6 +21,7 @@ import threading import time from wsgiref import simple_server +import netaddr from oslo_concurrency import processutils from oslo_config import cfg from oslo_log import log @@ -214,7 +215,12 @@ class IronicPythonAgent(base.ExecuteCommandMixin): return try: - return out.strip().split('\n')[0].split('src')[1].split()[0] + source = out.strip().split('\n')[0].split('src')[1].split()[0] + if netaddr.IPAddress(source).is_link_local(): + LOG.info('Ignoring link-local source to %(dest)s: %(rec)s', + {'dest': dest, 'rec': out}) + return + return source except IndexError: LOG.warning('No route to host %(dest)s, route record: %(rec)s', {'dest': dest, 'rec': out}) diff --git a/ironic_python_agent/tests/unit/test_agent.py b/ironic_python_agent/tests/unit/test_agent.py index 4de211e95..d1808e0b9 100644 --- a/ironic_python_agent/tests/unit/test_agent.py +++ b/ironic_python_agent/tests/unit/test_agent.py @@ -504,6 +504,14 @@ class TestBaseAgent(ironic_agent_base.IronicAgentTest): source = self.agent._get_route_source('XXX') self.assertEqual('1:2::3:4', source) + @mock.patch.object(utils, 'execute', autospec=True) + def test_get_route_source_ipv6_linklocal(self, mock_execute): + mock_execute.return_value = ( + 'XXX src fe80::1234:1234:1234:1234 metric XXX\n cache', None) + + source = self.agent._get_route_source('XXX') + self.assertIsNone(source) + @mock.patch.object(agent, 'LOG', autospec=True) @mock.patch.object(utils, 'execute', autospec=True) def test_get_route_source_indexerror(self, mock_execute, mock_log): diff --git a/releasenotes/notes/no-link-local-2e861978c5c7bf30.yaml b/releasenotes/notes/no-link-local-2e861978c5c7bf30.yaml new file mode 100644 index 000000000..3b3426156 --- /dev/null +++ b/releasenotes/notes/no-link-local-2e861978c5c7bf30.yaml @@ -0,0 +1,6 @@ +--- +fixes: + - Fixes the issue where link-local IP addresses were sometimes used as part + of the callback URL given to ironic. The routable address is used instead. + See `bug 1732692 `_ + for more details.