diff --git a/neutron/agent/common/ovs_lib.py b/neutron/agent/common/ovs_lib.py
index 4e989043516..a0fb64e5ba9 100644
--- a/neutron/agent/common/ovs_lib.py
+++ b/neutron/agent/common/ovs_lib.py
@@ -260,6 +260,18 @@ class OVSBridge(BaseOVS):
def set_agent_uuid_stamp(self, val):
self._default_cookie = val
+ def disable_in_band(self):
+ """Disable in-band remote management for the bridge.
+
+ That configuration will apply to all controllers configured for the
+ bridge.
+ """
+ other_config = {
+ 'disable-in-band': 'true'}
+ self.ovsdb.db_set(
+ 'Bridge', self.br_name,
+ ('other_config', other_config)).execute(check_error=True)
+
def set_controller(self, controllers):
self.ovsdb.set_controller(self.br_name,
controllers).execute(check_error=True)
@@ -748,13 +760,6 @@ class OVSBridge(BaseOVS):
msg = _('Unable to determine mac address for %s') % self.br_name
raise Exception(msg)
- def set_controllers_connection_mode(self, connection_mode):
- """Set bridge controllers connection mode.
-
- :param connection_mode: "out-of-band" or "in-band"
- """
- self.set_controller_field('connection_mode', connection_mode)
-
def set_controllers_inactivity_probe(self, interval):
"""Set bridge controllers inactivity probe interval.
diff --git a/neutron/plugins/ml2/drivers/openvswitch/agent/openflow/native/ovs_bridge.py b/neutron/plugins/ml2/drivers/openvswitch/agent/openflow/native/ovs_bridge.py
index 355c5f8fddc..d6ed2c9bc31 100644
--- a/neutron/plugins/ml2/drivers/openvswitch/agent/openflow/native/ovs_bridge.py
+++ b/neutron/plugins/ml2/drivers/openvswitch/agent/openflow/native/ovs_bridge.py
@@ -70,6 +70,29 @@ class OVSAgentBridge(ofswitch.OpenFlowSwitchMixin,
self._cached_dpid = new_dpid
def setup_controllers(self, conf):
+ # NOTE(slaweq): Disable remote in-band management for all controllers
+ # in the bridge
+ #
+ # By default openvswitch uses "in-band" controller connection mode
+ # which adds hidden OpenFlow rules (only visible by issuing ovs-appctl
+ # bridge/dump-flows
) and leads to a network loop on br-tun. As of
+ # now the OF controller is hosted locally with OVS which fits the
+ # "out-of-band" mode. If the remote OF controller is ever to be
+ # supported by openvswitch agent in the future, "In-Band Control" [1]
+ # should be taken into consideration for physical bridge only, but
+ # br-int and br-tun must be configured with the "out-of-band"
+ # controller connection mode.
+ #
+ # Setting connection_mode for controllers should be done in single
+ # transaction together with controllers setup but it will be easier to
+ # disable in-band remote management for bridge which
+ # effectively means that this configurations will applied to all
+ # controllers in the bridge
+ #
+ # [1] https://github.com/openvswitch/ovs/blob/master/DESIGN.md
+ # [2] https://bugzilla.redhat.com/show_bug.cgi?id=2134772
+ self.disable_in_band()
+
controller = (
"tcp:%(address)s:%(port)s" % {
"address": conf.OVS.of_listen_address,
@@ -83,21 +106,6 @@ class OVSAgentBridge(ofswitch.OpenFlowSwitchMixin,
self.set_controller([controller])
self.add_protocols(ovs_consts.OPENFLOW13)
- # NOTE(ivc): Force "out-of-band" controller connection mode (see
- # "In-Band Control" [1]).
- #
- # By default openvswitch uses "in-band" controller connection mode
- # which adds hidden OpenFlow rules (only visible by issuing ovs-appctl
- # bridge/dump-flows
) and leads to a network loop on br-tun. As of
- # now the OF controller is hosted locally with OVS which fits the
- # "out-of-band" mode. If the remote OF controller is ever to be
- # supported by openvswitch agent in the future, "In-Band Control" [1]
- # should be taken into consideration for physical bridge only, but
- # br-int and br-tun must be configured with the "out-of-band"
- # controller connection mode.
- #
- # [1] https://github.com/openvswitch/ovs/blob/master/DESIGN.md
- self.set_controllers_connection_mode("out-of-band")
self.set_controllers_inactivity_probe(conf.OVS.of_inactivity_probe)
def drop_port(self, in_port):
diff --git a/neutron/tests/functional/agent/test_ovs_lib.py b/neutron/tests/functional/agent/test_ovs_lib.py
index bfed9b93201..2de4befbb9d 100644
--- a/neutron/tests/functional/agent/test_ovs_lib.py
+++ b/neutron/tests/functional/agent/test_ovs_lib.py
@@ -14,7 +14,6 @@
# under the License.
import collections
-import uuid
import mock
from neutron_lib import constants as const
@@ -136,6 +135,15 @@ class OVSBridgeTestCase(OVSBridgeTestBase):
self.br.del_controller()
self.assertEqual([], self.br.get_controller())
+ def test_disable_in_band(self):
+ self.br.disable_in_band()
+ br_other_config = self.ovs.ovsdb.db_find(
+ 'Bridge', ('name', '=', self.br.br_name), columns=['other_config']
+ ).execute()[0]['other_config']
+ self.assertEqual(
+ 'true',
+ br_other_config.get('disable-in-band', '').lower())
+
def test_non_index_queries(self):
controllers = ['tcp:127.0.0.1:6633']
self.br.set_controller(controllers)
@@ -391,33 +399,6 @@ class OVSBridgeTestCase(OVSBridgeTestBase):
self.br.delete_ports(all_ports=True)
self.assertEqual(len(self.br.get_port_name_list()), 0)
- def test_set_controller_connection_mode(self):
- controllers = ['tcp:192.0.2.0:6633']
- self._set_controllers_connection_mode(controllers)
-
- def test_set_multi_controllers_connection_mode(self):
- controllers = ['tcp:192.0.2.0:6633', 'tcp:192.0.2.1:55']
- self._set_controllers_connection_mode(controllers)
-
- def _set_controllers_connection_mode(self, controllers):
- self.br.set_controller(controllers)
- self.assertEqual(sorted(controllers), sorted(self.br.get_controller()))
- self.br.set_controllers_connection_mode('out-of-band')
- self._assert_controllers_connection_mode('out-of-band')
- self.br.del_controller()
- self.assertEqual([], self.br.get_controller())
-
- def _assert_controllers_connection_mode(self, connection_mode):
- controllers = self.br.db_get_val('Bridge', self.br.br_name,
- 'controller')
- controllers = [controllers] if isinstance(
- controllers, uuid.UUID) else controllers
- for controller in controllers:
- self.assertEqual(connection_mode,
- self.br.db_get_val('Controller',
- controller,
- 'connection_mode'))
-
def test_db_create_references(self):
with self.ovs.ovsdb.transaction(check_error=True) as txn:
queue = txn.add(self.ovs.ovsdb.db_create("Queue",
diff --git a/neutron/tests/unit/plugins/ml2/drivers/openvswitch/agent/openflow/native/ovs_bridge_test_base.py b/neutron/tests/unit/plugins/ml2/drivers/openvswitch/agent/openflow/native/ovs_bridge_test_base.py
index 7773f1fce2a..f7bedb32522 100644
--- a/neutron/tests/unit/plugins/ml2/drivers/openvswitch/agent/openflow/native/ovs_bridge_test_base.py
+++ b/neutron/tests/unit/plugins/ml2/drivers/openvswitch/agent/openflow/native/ovs_bridge_test_base.py
@@ -146,10 +146,9 @@ class OVSBridgeTestBase(ovs_test_base.OVSOSKenTestBase):
m_set_controller = mock.patch.object(self.br, 'set_controller')
m_set_probe = mock.patch.object(self.br,
'set_controllers_inactivity_probe')
- m_set_ccm = mock.patch.object(self.br,
- 'set_controllers_connection_mode')
+ m_disable_in_band = mock.patch.object(self.br, 'disable_in_band')
- with m_set_ccm as set_ccm, \
+ with m_disable_in_band as disable_in_band, \
m_add_protocols as add_protocols, \
m_set_controller as set_controller, \
m_get_controller as get_controller, \
@@ -162,7 +161,7 @@ class OVSBridgeTestBase(ovs_test_base.OVSOSKenTestBase):
set_controller.assert_not_called()
else:
set_controller.assert_called_once_with(["tcp:127.0.0.1:6633"])
- set_ccm.assert_called_once_with("out-of-band")
+ disable_in_band.assert_called_once_with()
add_protocols.assert_called_once_with(constants.OPENFLOW13)
def test_setup_controllers(self):