From 4808f91eb2c245344517fc89c37c6c4c88e9051b Mon Sep 17 00:00:00 2001 From: Isaku Yamahata Date: Thu, 12 Dec 2013 18:47:37 +0900 Subject: [PATCH] ml2: gre, vxlan type driver can leak segment_id When multiple region of segment_id is specified, segment_id can leak (will be never reused) on deletion of network. Change-Id: Ia27b7e2c0ff4ab58be304e54123a679a5e35ab00 Closes-Bug: #1260262 --- neutron/plugins/ml2/drivers/type_gre.py | 8 +++--- neutron/plugins/ml2/drivers/type_vxlan.py | 8 +++--- neutron/tests/unit/ml2/test_type_gre.py | 31 ++++++++++++++++++++++ neutron/tests/unit/ml2/test_type_vxlan.py | 32 +++++++++++++++++++++++ 4 files changed, 71 insertions(+), 8 deletions(-) diff --git a/neutron/plugins/ml2/drivers/type_gre.py b/neutron/plugins/ml2/drivers/type_gre.py index d0a9e5307..6c4c7eb81 100644 --- a/neutron/plugins/ml2/drivers/type_gre.py +++ b/neutron/plugins/ml2/drivers/type_gre.py @@ -120,10 +120,10 @@ class GreTypeDriver(type_tunnel.TunnelTypeDriver): LOG.debug(_("Releasing gre tunnel %s to pool"), gre_id) break - else: - session.delete(alloc) - LOG.debug(_("Releasing gre tunnel %s outside pool"), - gre_id) + else: + session.delete(alloc) + LOG.debug(_("Releasing gre tunnel %s outside pool"), + gre_id) except sa_exc.NoResultFound: LOG.warning(_("gre_id %s not found"), gre_id) diff --git a/neutron/plugins/ml2/drivers/type_vxlan.py b/neutron/plugins/ml2/drivers/type_vxlan.py index a5c7f1206..5366215f5 100644 --- a/neutron/plugins/ml2/drivers/type_vxlan.py +++ b/neutron/plugins/ml2/drivers/type_vxlan.py @@ -128,10 +128,10 @@ class VxlanTypeDriver(type_tunnel.TunnelTypeDriver): LOG.debug(_("Releasing vxlan tunnel %s to pool"), vxlan_vni) break - else: - session.delete(alloc) - LOG.debug(_("Releasing vxlan tunnel %s outside pool"), - vxlan_vni) + else: + session.delete(alloc) + LOG.debug(_("Releasing vxlan tunnel %s outside pool"), + vxlan_vni) except sa_exc.NoResultFound: LOG.warning(_("vxlan_vni %s not found"), vxlan_vni) diff --git a/neutron/tests/unit/ml2/test_type_gre.py b/neutron/tests/unit/ml2/test_type_gre.py index e17f337ea..ae7056a99 100644 --- a/neutron/tests/unit/ml2/test_type_gre.py +++ b/neutron/tests/unit/ml2/test_type_gre.py @@ -174,3 +174,34 @@ class GreTypeTest(base.BaseTestCase): for endpoint in endpoints: self.assertIn(endpoint['ip_address'], [TUNNEL_IP_ONE, TUNNEL_IP_TWO]) + + +class GreTypeMultiRangeTest(base.BaseTestCase): + + TUN_MIN0 = 100 + TUN_MAX0 = 101 + TUN_MIN1 = 200 + TUN_MAX1 = 201 + TUNNEL_MULTI_RANGES = [(TUN_MIN0, TUN_MAX0), (TUN_MIN1, TUN_MAX1)] + + def setUp(self): + super(GreTypeMultiRangeTest, self).setUp() + ml2_db.initialize() + self.driver = type_gre.GreTypeDriver() + self.driver.gre_id_ranges = self.TUNNEL_MULTI_RANGES + self.driver._sync_gre_allocations() + self.session = db.get_session() + self.addCleanup(db.clear_db) + + def test_release_segment(self): + segments = [self.driver.allocate_tenant_segment(self.session) + for i in range(4)] + + # Release them in random order. No special meaning. + for i in (0, 2, 1, 3): + self.driver.release_segment(self.session, segments[i]) + + for key in (self.TUN_MIN0, self.TUN_MAX0, + self.TUN_MIN1, self.TUN_MAX1): + alloc = self.driver.get_gre_allocation(self.session, key) + self.assertFalse(alloc.allocated) diff --git a/neutron/tests/unit/ml2/test_type_vxlan.py b/neutron/tests/unit/ml2/test_type_vxlan.py index e3b8ffa55..5380de421 100644 --- a/neutron/tests/unit/ml2/test_type_vxlan.py +++ b/neutron/tests/unit/ml2/test_type_vxlan.py @@ -194,3 +194,35 @@ class VxlanTypeTest(base.BaseTestCase): self.assertEqual(VXLAN_UDP_PORT_ONE, endpoint['udp_port']) elif endpoint['ip_address'] == TUNNEL_IP_TWO: self.assertEqual(VXLAN_UDP_PORT_TWO, endpoint['udp_port']) + + +class VxlanTypeMultiRangeTest(base.BaseTestCase): + + TUN_MIN0 = 100 + TUN_MAX0 = 101 + TUN_MIN1 = 200 + TUN_MAX1 = 201 + TUNNEL_MULTI_RANGES = [(TUN_MIN0, TUN_MAX0), (TUN_MIN1, TUN_MAX1)] + + def setUp(self): + super(VxlanTypeMultiRangeTest, self).setUp() + ml2_db.initialize() + self.driver = type_vxlan.VxlanTypeDriver() + self.driver.vxlan_vni_ranges = self.TUNNEL_MULTI_RANGES + self.driver._sync_vxlan_allocations() + self.session = db.get_session() + self.addCleanup(cfg.CONF.reset) + self.addCleanup(db.clear_db) + + def test_release_segment(self): + segments = [self.driver.allocate_tenant_segment(self.session) + for i in range(4)] + + # Release them in random order. No special meaning. + for i in (0, 2, 1, 3): + self.driver.release_segment(self.session, segments[i]) + + for key in (self.TUN_MIN0, self.TUN_MAX0, + self.TUN_MIN1, self.TUN_MAX1): + alloc = self.driver.get_vxlan_allocation(self.session, key) + self.assertFalse(alloc.allocated) -- 2.45.2