]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Suppress exception when trying to remove non existing device in SNAT redirect
authorGal Sagie <gal.sagie@huawei.com>
Mon, 30 Mar 2015 07:40:36 +0000 (10:40 +0300)
committerGal Sagie <gal.sagie@huawei.com>
Tue, 28 Apr 2015 05:23:11 +0000 (08:23 +0300)
L3 service plugin first calls to remove_router_interface from the L2 OVS agent
which delete this port from OVS and then the service plugin calls
to remove the router interface from L3 agent.

Catch the exception thrown on the delete gateway, if its due to device doesn't exists
ignore the exception

Closes-Bug: #1435012
Change-Id: Ieeaa01e7c0393f5200d1a8d2bbbc16befe7699a2

neutron/agent/l3/dvr_router.py
neutron/agent/linux/ip_lib.py
neutron/common/exceptions.py
neutron/tests/functional/agent/test_l3_agent.py

index 4d2539ff44f7415399458a1f37f243e1b1ad2404..d26770590bd3513e64e3469e418c9dd08f790667 100644 (file)
@@ -24,6 +24,7 @@ from neutron.agent.l3 import router_info as router
 from neutron.agent.linux import ip_lib
 from neutron.agent.linux import iptables_manager
 from neutron.common import constants as l3_constants
+from neutron.common import exceptions
 from neutron.common import utils as common_utils
 from neutron.i18n import _LE
 
@@ -246,6 +247,15 @@ class DvrRouter(router.RouterInfo):
             snat_idx = net.value
         return snat_idx
 
+    def _snat_delete_device_gateway(self, ns_ip_device, gw_ip_addr,
+                                    snat_idx):
+        try:
+            ns_ip_device.route.delete_gateway(gw_ip_addr,
+                                        table=snat_idx)
+        except exceptions.DeviceNotFoundError:
+            # Suppress device not exist exception
+            pass
+
     def _snat_redirect_modify(self, gateway, sn_port, sn_int, is_add):
         """Adds or removes rules and routes for SNAT redirection."""
         try:
@@ -271,8 +281,9 @@ class DvrRouter(router.RouterInfo):
                                 ['sysctl', '-w',
                                  'net.ipv4.conf.%s.send_redirects=0' % sn_int])
                         else:
-                            ns_ipd.route.delete_gateway(gw_ip_addr,
-                                                        table=snat_idx)
+                            self._snat_delete_device_gateway(ns_ipd,
+                                                             gw_ip_addr,
+                                                             snat_idx)
                             ns_ipr.rule.delete(sn_port_cidr, snat_idx,
                                                snat_idx)
                         break
index f2f0f9b090126350aa63ae9664cfd4ed02bc9f35..baf61b90e1bad8b9276caca5a277e0bc742282cd 100644 (file)
@@ -18,6 +18,7 @@ import netaddr
 import os
 from oslo_config import cfg
 from oslo_log import log as logging
+from oslo_utils import excutils
 
 from neutron.agent.common import utils
 from neutron.common import exceptions
@@ -406,7 +407,14 @@ class IpRouteCommand(IpDeviceCommandBase):
                 'dev', self.name]
         if table:
             args += ['table', table]
-        self._as_root([ip_version], tuple(args))
+        try:
+            self._as_root([ip_version], tuple(args))
+        except RuntimeError as rte:
+            with (excutils.save_and_reraise_exception()) as ctx:
+                if "Cannot find device" in rte.message:
+                    ctx.reraise = False
+                    raise exceptions.DeviceNotFoundError(
+                        device_name=self.name)
 
     def list_onlink_routes(self, ip_version):
         def iterate_routes():
index d5b64c52eb2f57d2313bea5a7aa113b283947e56..e5212ab4ebd4d22758c3a19519a58da56245bc15 100644 (file)
@@ -453,3 +453,7 @@ class SubnetPoolDeleteError(BadRequest):
 
 class SubnetPoolQuotaExceeded(OverQuota):
     message = _("Per-tenant subnet pool prefix quota exceeded")
+
+
+class DeviceNotFoundError(NeutronException):
+    message = _("IP Device '%(device_name)s' does not exist")
index d21ee536fa31311ae3b3c5a97d0765ed968d60e1..30f29d4e3818f399d0c5578651e63d52efc4d957 100755 (executable)
@@ -1091,6 +1091,7 @@ class TestDvrRouter(L3AgentTestFramework):
         )
         if gateway_expected_in_snat_namespace:
             self._assert_dvr_snat_gateway(router)
+            self._assert_removal_of_already_deleted_gateway_device(router)
 
         snat_namespace_should_not_exist = (
             self.agent.conf.agent_mode == 'dvr'
@@ -1111,6 +1112,16 @@ class TestDvrRouter(L3AgentTestFramework):
         expected_gateway = external_port['subnets'][0]['gateway_ip']
         self.assertEqual(expected_gateway, existing_gateway)
 
+    def _assert_removal_of_already_deleted_gateway_device(self, router):
+        namespace = dvr_snat_ns.SnatNamespace.get_snat_ns_name(
+            router.router_id)
+        device = ip_lib.IPDevice("fakedevice",
+                                 namespace=namespace)
+
+        # Assert that no exception is thrown for this case
+        self.assertIsNone(router._snat_delete_device_gateway(
+                          device, "192.168.0.1", 0))
+
     def _assert_snat_namespace_does_not_exist(self, router):
         namespace = dvr_snat_ns.SnatNamespace.get_snat_ns_name(
             router.router_id)