DVR: Fix dvr_no_external agent restart with fips

Centralized floating IP return to Error state when
the 'dvr_no_external' agent restarts.
The sync data received from the server was not handling
the agent properly and so was not update the 'dvr_snat_bound'
flag.
This would initiate an floating IP Error state.
This patch will fix the issue mentioned above.

Closes-Bug: #1741411
Change-Id: Id1cf26ffba8262ba7b3e5f41faa4cb28ba9dcb7d
(cherry picked from commit 477d4135ba)
This commit is contained in:
Swaminathan Vasudevan 2018-01-10 14:45:29 -08:00
parent f9fcf5e34a
commit 5b0a0f5d97
2 changed files with 39 additions and 10 deletions

View File

@ -726,27 +726,46 @@ class _DVRAgentInterfaceMixin(object):
# All unbound ports with floatingip irrespective of
# the device owner should be included as valid ports
# and updated.
port_host = port[portbindings.HOST_ID]
if (port_host == host or port_in_migration or
if (port_in_migration or
self._is_unbound_port(port)):
port_dict.update({port['id']: port})
if port_host and port_host != host:
# Consider the ports where the portbinding host and
# request host does not match.
continue
port_host = port[portbindings.HOST_ID]
if port_host:
l3_agent_on_host = self.get_l3_agents(
context,
filters={'host': [port_host]})
l3_agent_mode = ''
if len(l3_agent_on_host):
l3_agent_mode = self._get_agent_mode(
l3_agent_on_host[0])
# If the agent requesting is dvr_snat but
# the portbinding host resides in dvr_no_external
# agent then include the port.
requesting_agent_mode = self._get_agent_mode(agent)
requesting_agent_mode = self._get_agent_mode(agent)
# Consider the ports where the portbinding host and
# request host match.
if port_host == host:
# Check for agent type before adding the port_dict.
# For VMs that are hosted on the dvr_no_external
# agent and if the request is coming from the same
# agent on re-syncs then we need to add the appropriate
# port['agent'] before updating the dict.
if (l3_agent_mode == (
l3_const.L3_AGENT_MODE_DVR_NO_EXTERNAL) and
requesting_agent_mode == (
const.L3_AGENT_MODE_DVR_SNAT)):
l3_const.L3_AGENT_MODE_DVR_NO_EXTERNAL)):
port['agent'] = (
l3_const.L3_AGENT_MODE_DVR_NO_EXTERNAL)
port_dict.update({port['id']: port})
# Consider the ports where the portbinding host and
# request host does not match.
else:
# If the agent requesting is dvr_snat but
# the portbinding host resides in dvr_no_external
# agent then include the port.
if (l3_agent_mode == (
l3_const.L3_AGENT_MODE_DVR_NO_EXTERNAL) and
requesting_agent_mode == (
const.L3_AGENT_MODE_DVR_SNAT)):
port['agent'] = (
l3_const.L3_AGENT_MODE_DVR_NO_EXTERNAL)
port_dict.update({port['id']: port})

View File

@ -969,6 +969,16 @@ class L3DvrTestCase(L3DvrTestCaseBase):
self.context, self.l3_agent['host'], [router['id']]))
floatingips = router_info[0][constants.FLOATINGIP_KEY]
self.assertTrue(floatingips[0][n_const.DVR_SNAT_BOUND])
# Test case to make sure when an agent in this case
# dvr_no_external restarts and does a full sync, we need
# to make sure that the returned router_info has
# DVR_SNAT_BOUND flag enabled, otherwise the floating IP
# state would error out.
router_sync_info = (
self.l3_plugin.list_active_sync_routers_on_active_l3_agent(
self.context, HOST1, [router['id']]))
floatingips = router_sync_info[0][constants.FLOATINGIP_KEY]
self.assertTrue(floatingips[0][n_const.DVR_SNAT_BOUND])
def test_allowed_addr_pairs_delayed_fip_and_update_arp_entry(self):
HOST1 = 'host1'