cur_ports = self.int_br.get_vif_port_set()
self.int_br_device_count = len(cur_ports)
port_info = {'current': cur_ports}
+ if updated_ports is None:
+ updated_ports = set()
+ updated_ports.update(self._find_lost_vlan_port(registered_ports))
if updated_ports:
# Some updated ports might have been removed in the
# meanwhile, and therefore should not be processed.
port_info['removed'] = registered_ports - cur_ports
return port_info
+ def _find_lost_vlan_port(self, registered_ports):
+ """Return ports which have lost their vlan tag.
+
+ The returned value is a set of port ids of the ports concerned by a
+ vlan tag loss.
+ """
+ port_tags = self.int_br.get_port_tag_dict()
+ changed_ports = set()
+ for lvm in self.local_vlan_map.values():
+ for port in registered_ports:
+ if (
+ port in lvm.vif_ports
+ and lvm.vif_ports[port].port_name in port_tags
+ and port_tags[lvm.vif_ports[port].port_name] != lvm.vlan
+ ):
+ LOG.info(
+ _("Port '%(port_name)s' has lost "
+ "its vlan tag '%(vlan_tag)d'!"),
+ {'port_name': lvm.vif_ports[port].port_name,
+ 'vlan_tag': lvm.vlan}
+ )
+ changed_ports.add(port)
+ return changed_ports
+
def update_ancillary_ports(self, registered_ports):
ports = set()
for bridge in self.ancillary_brs:
import testtools
from neutron.agent.linux import ip_lib
+from neutron.agent.linux import ovs_lib
from neutron.agent.linux import utils
from neutron.openstack.common import importutils
from neutron.plugins.common import constants as p_const
self._test_port_dead(self.mod_agent.DEAD_VLAN_TAG)
def mock_scan_ports(self, vif_port_set=None, registered_ports=None,
- updated_ports=None):
- with mock.patch.object(self.agent.int_br, 'get_vif_port_set',
- return_value=vif_port_set):
+ updated_ports=None, port_tags_dict=None):
+ port_tags_dict = port_tags_dict or {}
+ with contextlib.nested(
+ mock.patch.object(self.agent.int_br, 'get_vif_port_set',
+ return_value=vif_port_set),
+ mock.patch.object(self.agent.int_br, 'get_port_tag_dict',
+ return_value=port_tags_dict)
+ ):
return self.agent.scan_ports(registered_ports, updated_ports)
def test_scan_ports_returns_current_only_for_unchanged_ports(self):
updated_ports)
self.assertEqual(expected, actual)
+ def test_update_ports_returns_lost_vlan_port(self):
+ br = self.mod_agent.OVSBridge('br-int', 'fake_helper', self.ryuapp)
+ mac = "ca:fe:de:ad:be:ef"
+ port = ovs_lib.VifPort(1, 1, 1, mac, br)
+ lvm = self.mod_agent.LocalVLANMapping(
+ 1, '1', None, 1, {port.vif_id: port})
+ local_vlan_map = {'1': lvm}
+ vif_port_set = set([1, 3])
+ registered_ports = set([1, 2])
+ port_tags_dict = {1: []}
+ expected = dict(
+ added=set([3]), current=vif_port_set,
+ removed=set([2]), updated=set([1])
+ )
+ with mock.patch.dict(self.agent.local_vlan_map, local_vlan_map):
+ actual = self.mock_scan_ports(
+ vif_port_set, registered_ports, port_tags_dict=port_tags_dict)
+ self.assertEqual(expected, actual)
+
def test_treat_devices_added_returns_true_for_missing_device(self):
with mock.patch.object(self.agent.plugin_rpc, 'get_device_details',
side_effect=Exception()):