From 8d39f02d4637ca6409b8cfce4fcab8c91267fe19 Mon Sep 17 00:00:00 2001 From: jufeng Date: Mon, 3 Feb 2020 14:54:12 +0800 Subject: [PATCH] Support gateway which is not in subnet CIDR in ha_router There is case that gateway is not in subnet CIDR. We can set 2 routes as follows to support this: ip route add 172.16.0.1/32 dev eth0 ip route add default via 172.16.0.1 dev eth0 Conflicts: neutron/agent/l3/ha_router.py Closes-bug: #1861674 Change-Id: I69356e926b15de7f1f99540e7cb98671c634e8a9 (cherry picked from commit 554b5c226750ec75e99ebce241df8b7a700ff016) --- neutron/agent/l3/ha_router.py | 9 +++++++++ neutron/tests/unit/agent/l3/test_ha_router.py | 4 ++++ 2 files changed, 13 insertions(+) diff --git a/neutron/agent/l3/ha_router.py b/neutron/agent/l3/ha_router.py index aaa2b1ef63e..c165f000a07 100644 --- a/neutron/agent/l3/ha_router.py +++ b/neutron/agent/l3/ha_router.py @@ -30,6 +30,7 @@ from neutron.agent.linux import ip_lib from neutron.agent.linux import keepalived from neutron.common import constants as const from neutron.common import utils as common_utils +from neutron.ipam import utils as ipam_utils LOG = logging.getLogger(__name__) HA_DEV_PREFIX = 'ha-' @@ -270,6 +271,14 @@ class HaRouter(router.RouterInfo): default_gw_rts = [] instance = self._get_keepalived_instance() + for subnet in ex_gw_port.get('subnets', []): + is_gateway_not_in_subnet = (subnet['gateway_ip'] and + not ipam_utils.check_subnet_ip( + subnet['cidr'], + subnet['gateway_ip'])) + if is_gateway_not_in_subnet: + default_gw_rts.append(keepalived.KeepalivedVirtualRoute( + subnet['gateway_ip'], None, interface_name, scope='link')) for gw_ip in gateway_ips: # TODO(Carl) This is repeated everywhere. A method would # be nice. diff --git a/neutron/tests/unit/agent/l3/test_ha_router.py b/neutron/tests/unit/agent/l3/test_ha_router.py index a44745267b4..4224b91c27e 100644 --- a/neutron/tests/unit/agent/l3/test_ha_router.py +++ b/neutron/tests/unit/agent/l3/test_ha_router.py @@ -77,6 +77,10 @@ class TestBasicRouterOperations(base.BaseTestCase): ri._add_default_gw_virtual_route(ex_gw_port, 'qg-abc') self.assertEqual(0, len(mock_instance.virtual_routes.gateway_routes)) + subnets[1]['gateway_ip'] = '30.0.1.1' + ri._add_default_gw_virtual_route(ex_gw_port, 'qg-abc') + self.assertEqual(2, len(mock_instance.virtual_routes.gateway_routes)) + @mock.patch.object(router_info.RouterInfo, 'remove_floating_ip') def test_remove_floating_ip(self, super_remove_floating_ip): ri = self._create_router(mock.MagicMock())