From 07050db1d1b27f0d7c7e662324feceac1420f8d9 Mon Sep 17 00:00:00 2001 From: Derek Higgins Date: Thu, 16 Nov 2017 12:38:21 +0000 Subject: [PATCH] Ignore IPv6 link local addresses Prevent IPA from picking up the IPv6 link-local address as a callback_url in cases where it gets tried before other addressing methods havn't complete yet. In this scenario IPA sleeps for 10 seconds and then retries giving the nic a chance to configure its routable IP address. Change-Id: Ic53334c630180f0d77bb0231e548d2c44bfe55ca Closes-Bug: #1732692 (cherry picked from commit 214790d17e35edd48e1b18f3ceabba91859e3247) --- ironic_python_agent/agent.py | 8 +++++++- ironic_python_agent/tests/unit/test_agent.py | 8 ++++++++ releasenotes/notes/no-link-local-2e861978c5c7bf30.yaml | 6 ++++++ 3 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 releasenotes/notes/no-link-local-2e861978c5c7bf30.yaml 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 1b0843072..d8d0e93e5 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.