]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Fix dvr_local_router.floating_ip_added_dist failure after agent restart
authorErik Colnick <erik.colnick@hp.com>
Wed, 11 Nov 2015 11:44:42 +0000 (04:44 -0700)
committerErik Colnick <erik.colnick@hp.com>
Wed, 11 Nov 2015 14:22:31 +0000 (07:22 -0700)
If DVR is enabled and an l3-agent is restarted, associating a floatingip
to an existing vm on the compute node where the l3-agent was restarted
will fail.  This commit fixes the floating_ip_added_dist method in
dvr_local_router.py so that self.rtr_fip_subnet will be created if
it is 'None' prior to the attempt to call the get_name() method on
it.

Change-Id: I860ee3522275f62f393e66853e53ef387598983d
CLoses-Bug: #1515341

neutron/agent/l3/dvr_local_router.py
neutron/tests/unit/agent/l3/test_dvr_local_router.py

index e02ae7362ee5e5f75e3d466c578e59668926bc19..8dd789ed3f8a88cd5322e6f241c1b58090981247 100644 (file)
@@ -89,6 +89,9 @@ class DvrLocalRouter(dvr_router_base.DvrRouterBase):
                          priority=rule_pr)
         #Add routing rule in fip namespace
         fip_ns_name = self.fip_ns.get_name()
+        if self.rtr_fip_subnet is None:
+            self.rtr_fip_subnet = self.fip_ns.local_subnets.allocate(
+                self.router_id)
         rtr_2_fip, _ = self.rtr_fip_subnet.get_pair()
         device = ip_lib.IPDevice(fip_2_rtr_name, namespace=fip_ns_name)
         device.route.add_route(fip_cidr, str(rtr_2_fip.ip))
index 8cb1fb429ff7b2a14f0e67651d28e763f9fdc374..fb7baf3fabb41af58e35231b9b59745126db83c8 100644 (file)
@@ -194,14 +194,27 @@ class TestDvrRouterOperations(base.BaseTestCase):
         ri.fip_ns = mock.Mock()
         ri.fip_ns.agent_gateway_port = agent_gw_port
         ri.fip_ns.allocate_rule_priority.return_value = FIP_PRI
-        ri.rtr_fip_subnet = lla.LinkLocalAddressPair('169.254.30.42/31')
+        subnet = lla.LinkLocalAddressPair('169.254.30.42/31')
+        ri.rtr_fip_subnet = subnet
+        ri.fip_ns.local_subnets = mock.Mock()
+        ri.fip_ns.local_subnets.allocate.return_value = subnet
         ri.dist_fip_count = 0
         ip_cidr = common_utils.ip_to_cidr(fip['floating_ip_address'])
         ri.floating_ip_added_dist(fip, ip_cidr)
         mIPRule().rule.add.assert_called_with(ip='192.168.0.1',
                                               table=16,
                                               priority=FIP_PRI)
+        ri.fip_ns.local_subnets.allocate.assert_not_called()
         self.assertEqual(1, ri.dist_fip_count)
+
+        # Validate that fip_ns.local_subnets is called when
+        # rtr_fip_subnet is None
+        ri.rtr_fip_subnet = None
+        ri.floating_ip_added_dist(fip, ip_cidr)
+        mIPRule().rule.add.assert_called_with(ip='192.168.0.1',
+                                              table=16,
+                                              priority=FIP_PRI)
+        ri.fip_ns.local_subnets.allocate.assert_called_once_with(ri.router_id)
         # TODO(mrsmith): add more asserts
 
     @mock.patch.object(ip_lib, 'IPWrapper')
@@ -232,15 +245,19 @@ class TestDvrRouterOperations(base.BaseTestCase):
         ri.fip_ns.agent_gateway_port = agent_gw_port
         s = lla.LinkLocalAddressPair('169.254.30.42/31')
         ri.rtr_fip_subnet = s
+        ri.fip_ns.local_subnets = mock.Mock()
         ri.floating_ip_removed_dist(fip_cidr)
         mIPRule().rule.delete.assert_called_with(
             ip=str(netaddr.IPNetwork(fip_cidr).ip), table=16, priority=FIP_PRI)
         mIPDevice().route.delete_route.assert_called_with(fip_cidr, str(s.ip))
         self.assertFalse(ri.fip_ns.unsubscribe.called)
+        ri.fip_ns.local_subnets.allocate.assert_not_called()
 
         ri.dist_fip_count = 1
-        ri.rtr_fip_subnet = lla.LinkLocalAddressPair('15.1.2.3/32')
-        _, fip_to_rtr = ri.rtr_fip_subnet.get_pair()
+        s1 = lla.LinkLocalAddressPair('15.1.2.3/32')
+        ri.rtr_fip_subnet = None
+        ri.fip_ns.local_subnets.allocate.return_value = s1
+        _, fip_to_rtr = s1.get_pair()
         fip_ns = ri.fip_ns
         ri.floating_ip_removed_dist(fip_cidr)
         self.assertTrue(fip_ns.destroyed)
@@ -249,6 +266,7 @@ class TestDvrRouterOperations(base.BaseTestCase):
         mIPDevice().route.delete_gateway.assert_called_once_with(
             str(fip_to_rtr.ip), table=16)
         fip_ns.unsubscribe.assert_called_once_with(ri.router_id)
+        ri.fip_ns.local_subnets.allocate.assert_called_once_with(ri.router_id)
 
     def _test_add_floating_ip(self, ri, fip, is_failure):
         ri._add_fip_addr_to_device = mock.Mock(return_value=is_failure)