From 99814b280fbdf8169d291e003cf6dc5a80e08074 Mon Sep 17 00:00:00 2001 From: Bence Romsics Date: Tue, 25 Jun 2024 15:52:23 +0200 Subject: [PATCH] Do not add taps in trunk bridges to the dead vlan When using neutron trunks, the tpi port is meant to be put in the dead vlan, not the tap, therefore 1) we no longer add taps in trunk bridges to the dead vlan in order to avoid bug #2069543. While working on this I realized a related problem: In neutron we changed how the dead vlan is handled. Instead of simply setting tag=4095 we set (beyond having a drop rule for tag 4095): tag : 4095 trunks : [4095] vlan_mode : trunk We do this not with the intention of making the port a trunk, but with the intention of dropping all traffic arriving on the port. For details please see the following patches: neutron $ git log --oneline --no-merges --grep='dead vlan' -2 0ddca28454 Make sure "dead vlan" ports cannot transmit packets 7aae31c9f9 Make the dead vlan actually dead Therefore 2) this patch also starts handling ports in the dead vlan as neutron does. Change-Id: I4f80d94bc1f346fd0a7ad0b9d684792f1451cf24 Closes-Bug: #2069543 Related-Bug: #1734320 Related-Bug: #1930414 Related-Bug: #1959564 --- vif_plug_ovs/ovs.py | 6 +++- vif_plug_ovs/ovsdb/ovsdb_lib.py | 7 +++- vif_plug_ovs/tests/functional/test_plugin.py | 35 ++++++++++++++++++++ vif_plug_ovs/tests/unit/test_plugin.py | 5 ++- 4 files changed, 50 insertions(+), 3 deletions(-) diff --git a/vif_plug_ovs/ovs.py b/vif_plug_ovs/ovs.py index 4a719ea7..e671a9ee 100644 --- a/vif_plug_ovs/ovs.py +++ b/vif_plug_ovs/ovs.py @@ -208,8 +208,12 @@ class OvsPlugin(plugin.PluginBase): # bound the interface in the vif binding details so isolation # can be enabled automatically in the future. bridge = kwargs.pop('bridge', vif.network.bridge) - if self._isolate_vif(vif_name, bridge): + # See bug #2069543. + if (self._isolate_vif(vif_name, bridge) and + not self._is_trunk_bridge(bridge)): kwargs['tag'] = constants.DEAD_VLAN + kwargs['vlan_mode'] = 'trunk' + kwargs['trunks'] = constants.DEAD_VLAN qos_type = self._get_qos_type(vif) if qos_type is not None: # NOTE(sean-k-mooney): If the port is not already created diff --git a/vif_plug_ovs/ovsdb/ovsdb_lib.py b/vif_plug_ovs/ovsdb/ovsdb_lib.py index f88f5672..00af91cf 100644 --- a/vif_plug_ovs/ovsdb/ovsdb_lib.py +++ b/vif_plug_ovs/ovsdb/ovsdb_lib.py @@ -145,7 +145,7 @@ class BaseOVS(object): self, bridge, dev, iface_id, mac, instance_id, mtu=None, interface_type=None, vhost_server_path=None, tag=None, pf_pci=None, vf_num=None, set_ids=True, datapath_type=None, - qos_type=None + qos_type=None, vlan_mode=None, trunks=None ): """Create OVS port @@ -210,6 +210,11 @@ class BaseOVS(object): txn.add(self.ovsdb.add_port(bridge, dev)) if tag: txn.add(self.ovsdb.db_set('Port', dev, ('tag', tag))) + if vlan_mode: + txn.add(self.ovsdb.db_set('Port', dev, + ('vlan_mode', vlan_mode))) + if trunks: + txn.add(self.ovsdb.db_set('Port', dev, ('trunks', trunks))) if qid: txn.add(self.ovsdb.db_set('Port', dev, ('qos', qid))) if col_values: diff --git a/vif_plug_ovs/tests/functional/test_plugin.py b/vif_plug_ovs/tests/functional/test_plugin.py index e40ae49a..e0b2d1e6 100644 --- a/vif_plug_ovs/tests/functional/test_plugin.py +++ b/vif_plug_ovs/tests/functional/test_plugin.py @@ -12,6 +12,7 @@ import testscenarios import time +from unittest import mock from oslo_concurrency import processutils from oslo_config import cfg @@ -183,3 +184,37 @@ class TestOVSPlugin(testscenarios.WithScenarios, self._check_parameter( 'QoS', str(qos_uuid), 'type', None ) + + def test_plug_br_int_isolate_vif_dead_vlan(self): + with mock.patch.object(self.plugin.config, 'isolate_vif', True): + network = objects.network.Network( + id='5449523c-3a08-11ef-86d6-17149687aa4d', + bridge='br-5449523c', + subnets=self.subnets, + vlan=99) + vif = objects.vif.VIFOpenVSwitch( + id='85cb9bc6-3a08-11ef-b2d4-9b7c38edd677', + address='ca:fe:de:ad:be:ef', + network=network, + port_profile=self.profile_ovs_system, + vif_name="port-85cb9bc6") + self.plugin.plug(vif, self.instance) + self.addCleanup(self._del_bridge, 'br-5449523c') + self._check_parameter('Port', vif.vif_name, 'tag', 4095) + + def test_plug_trunk_bridge_ignores_isolate_vif(self): + with mock.patch.object(self.plugin.config, 'isolate_vif', True): + network = objects.network.Network( + id='ef98b384-3a0f-11ef-9009-47345fca266f', + bridge='tbr-ef98b384', + subnets=self.subnets, + vlan=99) + vif = objects.vif.VIFOpenVSwitch( + id='631f52bc-3a07-11ef-a006-1319ef9d6edd', + address='ca:fe:de:ad:be:ef', + network=network, + port_profile=self.profile_ovs_system, + vif_name='port-631f52bc') + self.plugin.plug(vif, self.instance) + self.addCleanup(self._del_bridge, 'tbr-ef98b384') + self._check_parameter('Port', vif.vif_name, 'tag', []) diff --git a/vif_plug_ovs/tests/unit/test_plugin.py b/vif_plug_ovs/tests/unit/test_plugin.py index 83cc9c3c..9f5e0655 100644 --- a/vif_plug_ovs/tests/unit/test_plugin.py +++ b/vif_plug_ovs/tests/unit/test_plugin.py @@ -219,7 +219,10 @@ class PluginTest(testtools.TestCase): self.vif_ovs.address, self.instance.uuid, mtu=plugin.config.network_device_mtu, interface_type=constants.OVS_VHOSTUSER_INTERFACE_TYPE, - tag=constants.DEAD_VLAN) + tag=constants.DEAD_VLAN, + vlan_mode='trunk', + trunks=constants.DEAD_VLAN + ) @mock.patch.object(ovsdb_lib.BaseOVS, 'create_ovs_vif_port') @mock.patch.object(ovsdb_lib.BaseOVS, 'port_exists')