Merge "[DVR] Don't populate unbound ports in router's ARP cache" into stable/train
This commit is contained in:
commit
470740e3bd
|
@ -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
|
||||
|
@ -68,6 +69,18 @@ def is_admin_state_down_necessary():
|
|||
return _IS_ADMIN_STATE_DOWN_NECESSARY
|
||||
|
||||
|
||||
# TODO(slaweq): this should be moved to neutron_lib.plugins.utils module
|
||||
def is_port_bound(port):
|
||||
active_binding = plugin_utils.get_port_binding_by_status_and_host(
|
||||
port.get("port_bindings", []), const.ACTIVE)
|
||||
if not active_binding:
|
||||
LOG.warning("Binding for port %s was not found.", port)
|
||||
return False
|
||||
return active_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.
|
||||
|
@ -1272,10 +1285,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
|
||||
]
|
||||
|
||||
|
||||
|
|
|
@ -1247,6 +1247,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(plugin_utils, 'can_port_be_bound_to_virtual_bridge',
|
||||
return_value=True)
|
||||
def test__get_assoc_data_valid_vnic_type(self, *args):
|
||||
|
|
Loading…
Reference in New Issue