Ensure dvr ha router gateway port binding host

There are some extreme conditions which will result the unbound
router gateway port. Then all the centralized floating IPs will
not be reachable since the gateway port was set to 4095 tag.

This patch adds the HA status to the router related port
processing code path. If it is HA router, the gateway port
will go to the right HA router processing code branch.

Closes-Bug: #1827754
Change-Id: Ida1c9f3a38171ea82adc2f11cb17945d6e2434be
This commit is contained in:
LIU Yulong 2019-04-24 14:19:36 +08:00
parent 2879cbc0f6
commit 3d99147e73
3 changed files with 35 additions and 1 deletions

View File

@ -147,7 +147,8 @@ class L3RpcCallback(object):
self._ensure_host_set_on_port(context, self._ensure_host_set_on_port(context,
gw_port_host, gw_port_host,
router.get('gw_port'), router.get('gw_port'),
router['id']) router['id'],
ha_router_port=router.get('ha'))
for p in router.get(constants.SNAT_ROUTER_INTF_KEY, []): for p in router.get(constants.SNAT_ROUTER_INTF_KEY, []):
self._ensure_host_set_on_port( self._ensure_host_set_on_port(
context, gw_port_host, p, router['id'], context, gw_port_host, p, router['id'],
@ -187,6 +188,10 @@ class L3RpcCallback(object):
# All ports, including ports created for SNAT'ing for # All ports, including ports created for SNAT'ing for
# DVR are handled here # DVR are handled here
try: try:
LOG.debug("Updating router %(router)s port %(port)s "
"binding host %(host)s",
{"router": router_id, "port": port['id'],
"host": host})
self.plugin.update_port( self.plugin.update_port(
context, context,
port['id'], port['id'],
@ -213,6 +218,10 @@ class L3RpcCallback(object):
# port binding will be corrected when an active is # port binding will be corrected when an active is
# elected. # elected.
try: try:
LOG.debug("Updating router %(router)s port %(port)s "
"binding host %(host)s",
{"router": router_id, "port": port['id'],
"host": host})
self.plugin.update_port( self.plugin.update_port(
context, context,
port['id'], port['id'],

View File

@ -760,6 +760,16 @@ class L3_HA_NAT_db_mixin(l3_dvr_db.L3_NAT_with_dvr_db_mixin,
ha_binding_agent.host == gateway_port_binding_host): ha_binding_agent.host == gateway_port_binding_host):
return ha_binding_agent.host return ha_binding_agent.host
LOG.debug("No gateway port host retrieved. HA router %(router_id)s "
"gateway port %(gw_port_id)s "
"binding host: %(host)s, status: %(status)s, "
"router HA bindings: %(ha_bindings)s",
{"router_id": router_id,
"gw_port_id": gateway_port['id'],
"host": gateway_port_binding_host,
"status": gateway_port_status,
"ha_bindings": ha_bindings})
def is_ha_router(router): def is_ha_router(router):
"""Return True if router to be handled is ha.""" """Return True if router to be handled is ha."""

View File

@ -4203,6 +4203,21 @@ class L3RpcCallbackTestCase(base.BaseTestCase):
actual_message = mock_log.call_args[0][0] % mock_log.call_args[0][1] actual_message = mock_log.call_args[0][0] % mock_log.call_args[0][1]
self.assertEqual(expected_message, actual_message) self.assertEqual(expected_message, actual_message)
def test__ensure_host_set_on_ports_dvr_ha_router_with_gatway(self):
context = mock.Mock()
host = "fake_host"
router_id = 'foo_router_id'
router = {"id": router_id,
"gw_port_host": host,
"gw_port": {"id": "foo_port_id"},
"distributed": True,
"ha": True}
mock__ensure = mock.Mock()
self.l3_rpc_cb._ensure_host_set_on_port = mock__ensure
self.l3_rpc_cb._ensure_host_set_on_ports(context, host, [router])
mock__ensure.assert_called_once_with(
context, host, router["gw_port"], router_id, ha_router_port=True)
class L3AgentDbIntTestCase(L3BaseForIntTests, L3AgentDbTestCaseBase): class L3AgentDbIntTestCase(L3BaseForIntTests, L3AgentDbTestCaseBase):