Browse Source

Merge "[DVR] Don't populate unbound ports in router's ARP cache" into stable/queens

changes/86/720686/1
Zuul 2 months ago
committed by Gerrit Code Review
parent
commit
c060478788
2 changed files with 42 additions and 1 deletions
  1. +13
    -1
      neutron/db/l3_dvr_db.py
  2. +29
    -0
      neutron/tests/unit/db/test_l3_dvr_db.py

+ 13
- 1
neutron/db/l3_dvr_db.py View File

@@ -16,6 +16,7 @@ import collections
import netaddr
from neutron_lib.api.definitions import l3 as l3_apidef
from neutron_lib.api.definitions import portbindings
from neutron_lib.api.definitions import portbindings_extended
from neutron_lib.api import validators
from neutron_lib.callbacks import events
from neutron_lib.callbacks import exceptions
@@ -56,6 +57,16 @@ LOG = logging.getLogger(__name__)
l3_dvr_db.register_db_l3_dvr_opts()


# TODO(slaweq): this should be moved to neutron_lib.plugins.utils module
def is_port_bound(port):
if port.port_binding:
LOG.warning("Binding for port %s was not found.", port)
return False
return port.port_binding[portbindings_extended.VIF_TYPE] not in [
portbindings.VIF_TYPE_UNBOUND,
portbindings.VIF_TYPE_BINDING_FAILED]


@registry.has_registry_receivers
class DVRResourceOperationHandler(object):
"""Contains callbacks for DVR operations.
@@ -1239,10 +1250,11 @@ class L3_NAT_with_dvr_db_mixin(_DVRAgentInterfaceMixin,

def get_ports_under_dvr_connected_subnet(self, context, subnet_id):
query = dvr_mac_db.get_ports_query_by_subnet_and_ip(context, subnet_id)
ports = [p for p in query.all() if is_port_bound(p)]
return [
self.l3plugin._core_plugin._make_port_dict(
port, process_extensions=False)
for port in query.all()
for port in ports
]




+ 29
- 0
neutron/tests/unit/db/test_l3_dvr_db.py View File

@@ -1070,6 +1070,35 @@ class L3DvrTestCase(test_db_base_plugin_v2.NeutronDbPluginV2TestCase):
self.assertTrue(
self.mixin.is_router_distributed(self.ctx, router_id))

@mock.patch.object(l3_dvr_db, "is_port_bound")
def test_get_ports_under_dvr_connected_subnet(self, is_port_bound_mock):
router_dict = {'name': 'test_router', 'admin_state_up': True,
'distributed': True}
router = self._create_router(router_dict)
with self.network() as network,\
self.subnet(network=network) as subnet:
fake_bound_ports_ids = []

def fake_is_port_bound(port):
return port['id'] in fake_bound_ports_ids

is_port_bound_mock.side_effect = fake_is_port_bound

for _ in range(4):
port_res = self.create_port(
network['network']['id'],
{'fixed_ips': [{'subnet_id': subnet['subnet']['id']}]})
port_id = self.deserialize(self.fmt, port_res)['port']['id']
if len(fake_bound_ports_ids) < 2:
fake_bound_ports_ids.append(port_id)

self.mixin.add_router_interface(self.ctx, router['id'],
{'subnet_id': subnet['subnet']['id']})
dvr_subnet_ports = self.mixin.get_ports_under_dvr_connected_subnet(
self.ctx, subnet['subnet']['id'])
dvr_subnet_ports_ids = [p['id'] for p in dvr_subnet_ports]
self.assertItemsEqual(fake_bound_ports_ids, dvr_subnet_ports_ids)

@mock.patch.object(l3_db, 'can_port_be_bound_to_virtual_bridge',
return_value=True)
def test__get_assoc_data_valid_vnic_type(self, *args):


Loading…
Cancel
Save